Messi ended his three-game run without a goal as he smashed home the opener from the penalty spot after Neymar had been felled by Ignazio Abate.
Sergio Busquets then headed home a second, but Milan were handed a lifeline just before half-time when Gerard Pique turned Kaka’s cross into his own net.
However, Messi made the game safe seven minutes from the end when he dinked the ball home from Cesc Fabregas’ pass.
Defeat still leaves Milan in second place in Group H, a point ahead of Ajax and two clear of Celtic after the Dutch champions beat the Scottish side 1-0 in the night’s other match.
An eighth meeting between the sides in just the past three seasons meant there was a more subdued atmosphere than would normally be expected for a meeting between two of Europe’s heavyweights.
However, Barca boss Gerardo Martino showed how intent he was on sewing up qualification as he named his strongest available side with the fit-again Adriano restored at left-back.
Milan boss Massimiliano Allegri, meanwhile, sprang a surprise by leaving Mario Balotelli on the bench with the former Real Madrid duo of Robinho and Kaka starting instead in attack.
Both Brazilians were largely isolated in the first half though as Barcelona controlled proceedings.
Xavi Hernandez pulled an early free-kick just wide before Neymar ought to have scored when played in by Messi, but he took a heavy touch and allowed Christian Abbiati to smother.
Milan’s defensive resistence was finally undone on the half-hour mark by a moment of madness from Abate as he pulled back Neymar inside the area and Messi converted from the spot for his fifth Champions League goal of the campaign.
Riccardo Montolivo then had Milan’s first effort on goal 10 minutes before the break with an angled drive that flew just past.
Messi could have had his second as he wriggled into some space inside the area and dinked the ball over Abbiati, but Philippe Mexes got back to clear the ball to safety.
Barca did double their advantage six minutes before half-time though when Xavi’s free-kick was easily headed home by the unmarked Busquets.
Adriano forced Abbiati into a finger-tip save moments later as Barca threatened to run riot, but incredibly Milan got back in the game with the last kick of the half when Pique turned Kaka’s cut-back into his own net.
Allegri then introduced Balotelli for the ineffective Robinho at the interval and the Italian international instantly brought a new dimension to the Milan attack with a fierce low drive that Victor Valdes did well to handle.
Messi had a goal rightly disallowed for offside and Andres Iniesta’s low drive was turned away by Abbiati as Barca went in search of a killer third goal.
However, Milan were nearly level on 63 minutes as a wonderful run from Balotelli took him past two Barca defenders and his cross was swept just wide from Kaka.
Neymar so nearly then produced one of the goals of the season as he waltzed past four Milan players only to skew his shot just wide, and seconds later Abbiati produced an incredible low stop to turn Alexis Sanchez’s effort from point-blank range behind.
But Messi did finally seal the three points with a cool finish into the roof of the net after a wonderful one-two with Fabregas.