A close-range finish from Mattia Valoti and a stunning strike from Sergio Floccari gave SPAL a 2-0 lead before the break at the Paolo Mazza.
SPAL were down a man shortly before the break, though, as Marco D'Alessandro was sent off late in the first half, but a sluggish Milan lacked a cutting edge in attack until Ibrahimovic came on as a substitute.
A composed finish from Rafael Leao pulled one back for Milan with 11 minutes to go before Vicari turned an Alexis Saelemaekers cross into his own net in added time.