Giovani was unable to get a touch on an inviting cross on the half-hour mark, while the hosts threatened again shortly before the break when Pereira's dangerous delivery ran through untouched.
Villarreal should have opened the scoring in the 45th minute when Giovani rolled the ball across for Javier Aquino, but the Mexican didn't put enough on his shot with an open goal to aim at, allowing Marc Bartra to get back and make the clearance.
They wouldn't have to wait much longer for the first goal, however, getting it in stoppage time of the first half as Cani raced on to Pereira's through-ball before slotting it into the bottom corner.
Messi attempted to inspire an equaliser for his side when he went on a mazy dribble before curling an effort towards the corner, but once again Asenjo was there to make the stop.
The visitors' luck was in again 12 minutes from time as Alves caused more problems with a delivery into the box, this time forcing Mateo Musacchio to nod the ball past his own keeper.
Messi came close to adding a third from a free kick in the 82nd minute, but he wouldn't have to wait long to complete the turnaround as he fired an effort into the bottom corner moments later after good work from Sergio Busquets.
That proved to be enough for Barcelona as they held out for three vital points that lift them back into second in the table.