It was an emotionally charged encounter at El Madrigal as both teams paid tribute to former Barcelona coach Tito Vilanova, who tragically lost his battle with cancer on Friday.
Vilanova – assistant to Pep Guardiola during his trophy-laden four-year spell at the club – assumed control of the senior team in 2012 and led them to their 22nd La Liga title last year.
Barca found themselves trailing at half-time after Cani's cool finish and Manuel Trigueros doubled the deficit after the break with a firm header.
The visitors fought back ferociously though, and were helped by two own goals from Gabriel and Mateo Musacchio.
Lionel Messi completed the turnaround with seven minutes to play, slotting past Villarreal goalkeeper Sergio Asenjo to cap an excellent team move.
The match was soured by a banana being thrown at Barcelona defender Dani Alves during the second half.
Barcelona are now four points behind leaders Atletico Madrid - who they play on the final day of the season - with three games to go.
Sergio Busquets struggled to hold back tears during the emotional minute's silence which preceded the match, while the Villarreal team donned shirts which paid homage to the late Vilanova.
The early proceedings were understandably subdued, but Messi had the first chance of the game in the 17th minute, with Asenjo producing an important save with his feet.
Barca continued to dominate possession, as usual, although Giovani dos Santos – who came through the ranks at the Camp Nou – was unable to punish his former side at the other end after a quick Villarreal break.
The hosts then claimed the lead on the stroke of half-time, as Cani coolly slotted his first-time shot into the bottom-right corner after collecting Jonathan Pereira's precise ball.
Barcelona began the second half in impressive fashion and looked likely to draw level as Messi's influence on the game grew.
The forward first saw a 25-yard curling effort palmed away by Asenjo, before the goalkeeper kept out two free-kick attempts from the Argentina star.
Villarreal were able to double their lead though, as Trigueros rose brilliantly to steer a pinpoint header past Jose Manuel Pinto from Javier Aquino's cross.
Barcelona finally scored in the 65th minute, with Gabriel diverting Alves' cut-back past his goalkeeper.
Another own goal was to follow, as Barca equalised after Musacchio headed Alves' delivery beyond Asenjo's reach.
And they completed their unlikely comeback in the 83rd minute, as Busquets' lofted ball was headed by Cesc Fabregas, with Messi on hand to steer the winner home.
Get the best features, fun and footballing frolics straight to your inbox every week.
Thank you for signing up to Four Four Two. You will receive a verification email shortly.
There was a problem. Please refresh the page and try again.