Milan snatch Champions League spot late on
Furious Siena, who went ahead in the 25th minute through Claudio Terzi, also had Christian Terlizzi harshly sent off in the 70th minute, almost immediately after Milan captain Massimo Ambrosini had been dismissed.
Milan scraped into third place with 72 points, two ahead of Fiorentina who won 5-1 at Pescara with an Adem Ljajic hat-trick and are likely to feel hugely aggrieved by the manner of Milan's win.
Injury-ravaged Inter Milan's nightmare season ended with a crushing 5-2 home defeat by Udinese, who finished fifth and joined Fioretina in the Europa League next season. Inter finished ninth.
Napoli, who had already clinched second place behind champions Juventus and a place in the Champions League group stage, lost 2-1 at AS Roma.
Serie A leading scorer Edinson Cavani scored Napoli's goal, taking his tally to 29, after Marquinho and Mattia Destro had scored for Roma.
Milan coach Massimiliano Allegri's future remained in the balance, despite receiving a late helping of good fortune in the historic Tuscan city.
"We finished the season the way we started, with suffering and difficulty," Allegri told RAI television.
Milan wasted a flurry of early chances as Antonio Nocerino fired wildly over from Ignazio Abete's cross and M'baye Niang missed the ball completely when all he had to do was turn in Robinho's cross from six metres.
The Italian media had billed the match as a formality for Milan and they looked casual and sloppy, as if believing they could score at will.
But Siena showed they would not simply roll over and when Terzi was left unmarked, he headed in Alessandro Rossini's cross in the 25th minute.
Balotelli smacked a header against the crossbar before half-time and then forced a good save from Gianluca Pegolo with a booming free-kick.
But Milan were generally shoddy and rarely looked like scoring.
Their situation appeared hopeless when Ambrosini was sent off but their fortune began to change immediately when Terlizzi was given a second yellow card for what appeared a harmless challenge.
The visitors won a penalty out of the blue when Balotelli crumpled under the slightest of touches from a defender and he stepped up to convert the spot-kick in the 84th minute, his 12th goal since his move from Manchester City in January.
Three minutes later, Milan won a controversial free-kick, the ball was chipped to Mexes and, although his first effort was saved by Pegolo, the ball rebounded to the French defender who fired in the winner.
Fiorentina took command at Pescara with three goals in an 12-minute first half spell.
Ljajic turned in Juan Cuadrado's low cross at the far post, then ran on to a Matias Fernandez pass to score, before Fernandez himself was on target with a low shot from outside the area.
Ljajic and Stevan Jovetic added two more goals early in the second half.
Inter found themselves 2-0 behind after 10 minutes at San Siro as Giampiero Pinzi and Maurizo Domizzo scored for Udinese. Juan Jesus pulled one back but Antonio Di Natale restored Udinese's two-goal lead with his 23rd goal of the season.
Gabriel Silva and Luis Muriel added two more for Udinese in the second half while Tommaso Rocchi replied in between.