Milan travelled to the Castellani stadium buoyed after a 2-0 defeat of Fiorentina last week that left Sinisa Mihajlovic's men 12 points behind leaders Napoli and within sight of the European qualifying places.
But the visitors had left themselves exposed on the half hour when Empoli forward Piotr Zielinski was unmarked to level Carlos Bacca's eighth-minute opener.
And the Milan defence was at fault on the hour when veteran striker Massimo Maccarone pounced at the back post to convert a rebound from teenaged goalkeeper Gianluigi Donnarumma to level again after Giacomo Bonaventura had restored their lead on 48 minutes.
Milan's sixth draw of the season left them in sixth place, with Empoli one point and two places further adrift.
Bacca spurned an opportunity to create a last-gasp chance, prompting Mihajlovic to speak to the Colombian directly after the final whistle.
But the Serbian coach said Bacca alone wasn't to blame.
"We came here to win and I'm disappointed because we took the lead twice and that should have been enough for victory," he told Sky Sport.
"We made mistakes but in the end it's a fair result."
He added: "Bacca wasn't the only culprit. We had a couple of late chances but we weren't clinical enough."
Mihajlovic kept faith with the side that stunned Fiorentina at the San Siro last week, when Balotelli made a five-minute cameo appearance from the bench following his recent return from a lengthy injury lay-off.
Yet it took only eight minutes for the visitors to break the deadlock, Bacca collecting Luca Antonelli's punt from midfield to run between two defenders and beat onrushing goalkeeper Lukasz Skorupski at his near post.
Empoli levelled just after the half hour with a well-worked move that drew Milan's defence to a decoy runner, allowing Zielinski a clear run on to Riccardo Saponara's ball to beat 16-year-old Milan 'keeper Donnarumma at his far post.
Milan spurned chances through M'Baye Niang and Bonaventura, who made up for a free-kick miss minutes after the restart with arguably the luckiest goal of the season so far.
An Empoli clearance smacked off the head of Niang, and as the Frenchman fell to the ground in pain the ball continued towards Bonaventura, who pounced to beat the onrushing Skorupski with a crisp strike from eight yards.
Milan's joy, however, was short-lived. Maccarone made up for an earlier effort that was ruled out for offside by firing a Donnarumma rebound past the prone keeper on 61 minutes.
It was the striker's ninth goal of the season and his third since setting social media alight after celebrating a pre-Christmas goal against Bologna by running to the sidelines to sip from a pint of lager.
It was enough to secure a share of the points for Marco Giampaolo's men and the Empoli coach said: "Over the 90 minutes there were times when we werent't doing too well, but we were up against a Milan side that were rejuvenated both physically and mentally.
"We tried to play our football... now we have to see if we can improve, perhaps in our mental approach."
Balotelli replaced Niang with 25 minutes remaining but the striker's first opportunity was a tame free-kick from 30 metres that was straight at Skorupski.
Milan spurned two late half-chances to snatch the win.
Balotelli should have done better with a cross that met traffic as Bacca was running towards goal.
In injury time the Colombian striker did well to steal possession in midfield but lost the ball on the edge of the area with Balotelli free to his right.
Champions Juventus, who sit two points behind leaders Napoli ahead of their visit to Sampdoria, are aiming for their 11th consecutive win when they host Roma in Turin Sunday.
Roma, who have one win in their last six outings, are fifth at nine points off the pace.