Antonio Cassano scored a late equaliser for the hosts when they were already down to 10 men to cancel out Gergely Rudolf's first-half opener.
It meant Milan failed to capitalise on second-placed Inter Milan's 1-1 draw at Brescia on Friday night, meaning they stay five points clear at the top.
That also allowed Napoli to drag themselves back into the title race with a 3-1 victory at Parma, leaving them a point behind Inter.
For Bari, who remain 12 points from safety, the draw with Milan was a welcome boost in an otherwise dire season.
But they will be kicking themselves for failing to hold onto their lead with a numerical advantage.
Milan now face the prospect of losing Ibrahimovic for the top-of-the-table derby with Inter in three weeks, depending on the length of his ban.
"Unfortunately he had this half-foul reaction," said his coach Massimiliano Allegri, who suggested it may be Ibrahimovic's recent dry spell in front of goal that riled him.
"He has to stay calm, these periods can happen. He shouldn't get annoyed because he hasn't scored for a month, he's giving a lot."
It was a second disappointment in a week for Milan after they crashed out of the Champions League with a 0-0 draw at Tottenham.
"We knew this game wasn't won before kick-off but we made things difficult by going behind in a terrible first half," added Allegri.
"We're disappointed and bitter. This week we've twice played well but not got what we deserved."
In a lively opening Milan looked full of verve as Ignazio Abate burst down the right and crossed for Robinho at the near post but his seventh-minute header was well off target.
Kamil Glik then threw himself in front of a Robinho shot after determined work from Ibrahimovic down the right before Gennaro Gattuso dragged an effort wide.
Ibrahimovic stung Bari shot-stopper Francois Gillet's hands with a fierce 20-yard free-kick on 27 minutes.
But the basement sitters stunned their illustrious hosts six minutes before the break.
Sergio Almiron took a quick free-kick, playing the ball past Milan's defensive wall for Rudolf to run onto and shoot across goalkeeper Christian Abbiati.
Milan came out for the second period with extra determination and Robinho soon had the ball in the net, only for it to be chalked off as he had strayed beyond the last defender.
Ibrahimovic also found the target on the hour mark but that, too, was disallowed as he had controlled the ball with his arm.
He also dragged a shot wide as Milan upped the pressure but the big Swede then lost his head and was sent off for petulantly striking Marco Rossi in the ribs.
Bari wasted two gilt-edged opportunities to close out the game through Almiron and Erik Huseklepp.
And they were made to pay as their fragile defence crumbled when full-back Luca Antonini got to the byline and pulled the ball back into the area for Cassano to volley home eight minutes from time.
Napoli won for the first time in three games despite turning around at the break 1-0 down to a strike from Raffaele Palladino.
The returning Ezequiel Lavezzi then set up Marek Hamsik, who returned the favour for the second goal, before Danielle Galloppa was sent off for the hosts and Christian Maggio added a late third.
Udinese moved into the top four and a Champions League qualifying place for the first time this season as Serie A top scorer Antonio Di Natale scored a brace in a 4-0 thrashing of Cagliari.
Lazio dropped to fifth after Francesco Totti also scored a brace to give Roma derby honours and move the giallorossi to four points off the top four.
It was a fifth straight derby victory for Roma, while Lazio finished with nine men after late dismissals for Stefan Radu and Francesco Matuzalem.