The champions are three points below Real Madrid, who have a game in hand, going into El Clasico next weekend.
Messi fired Barca into the lead from 25 yards and scuffed home a second, his 498th goal for the club, before Samuel Umtiti’s own goal gave La Real hope.
Paco Alcacer made it 3-1 before Xabi Prieto pulled one back.
Unlike a weakened Real Madrid, who beat Sporting Gijon by the same scoreline earlier in the day, Barca played a full-strength team.
Barcelona host Juventus on Wednesday in the Champions League quarter-final, having lost the first leg 3-0 in Italy.
But boss Luis Enrique decided he could not risk losing ground in the title race in order to keep his players fresh for that game.
Barca now go into a potentially season-defining week. After the Juventus match comes a trip to Madrid, where a win would send Enrique’s side top on the head-to-head rule – although Real would still have an extra game to play.
All the goals at the Nou Camp were scored in the first half, with three coming in the five minutes before the break.
Barcelona, who were without the suspended Neymar, had to hang on for periods.
La Real’s best chance to equalise came when Asier Illarramendi’s ambitious 50-yard free-kick had to be tipped over by a back-pedalling Marc-Andre ter Stegen