Juan Vargas gave the Viola the lead in the 27th minute with a deflected free-kick before Borja Valero wrapped up victory midway through the second half with a tap in.
The result was another blow to Milan, who are now winless in their last four games in all competitions and have won just two of their past nine league games to lie 10th in the standings. The defeat leaves them 16 points adrift of third-place Juventus and the last Champions League qualifying spot, with the pressure on coach Massimiliano Allegri likely to increase.
It seemed as if Milan would score the opener as they had several chances early on, most notably when Christian Zapata’s close range header went over the bar in the 17th minute.
Mario Balotelli also sent a strike skyward before Kaka set up Sulley Muntari, but the midfielder’s shot was straight at Fiorentina goalkeeper Norberto Neto.
Milan were left to rue their missed chances soon after when Vargas gave Fiorentina the lead, when he fired his free-kick into the wall only for it to take a wicked deflection and leave goalkeeper Gabriel stranded.
After the break, Milan had several more chances but they failed to find the vital cutting edge.
Walter Birsa and M’baye Niang both squandered opportunities to score while Riccardo Saponara flashed a shot over the bar.
Valero then added salt to the wound when he tapped in Fiorentina’s second from six yards after he latched onto the end of Riccardo Saponara’s cross.
Rider Matos could have made it three for the Viola in the 82nd minute as he put his shot inches wide, but regardless, Fiorentina were left to celebrate a satisfying victory.