The children, some of them tied up, were rescued through smashed windows at the back of the bus and no-one was badly hurt. Fourteen people suffered smoke inhalation.
The driver, a 47-year-old Italian citizen originally from Senegal, was arrested.
"No-one will survive," the driver was alleged to have said.
"It was a miracle, it could have been a massacre," Milan chief prosecutor Francesco Greco was quoted as saying.
A teacher who had been on board the bus said the suspect was known to be angry about Italy's migrant policy. Some reports said the man had shouted "stop the deaths in the Mediterranean".
How the drama started
Two classes of teenagers and their adult escort were being driven from a school in Vailati di Crema to a gym but took a different route on a provincial highway apparently heading for Milan's Linate airport, local reports said.
The ordeal then unfolded over the next 40 minutes.
When the suspect allegedly began addressing the passengers with a knife, a boy phoned a parent, who alerted the police.
It took some time before police tried to intercept the bus. The vehicle rammed into police cars before slowing down.
Italian reports said petrol had been sprinkled around the bus but police were able to smash the rear windows and let the passengers off before it burst into flames.
Milan prosecutors said they were investigating all possible motives including terrorism.
Italy's right-wing interior minister, Matteo Salvini, reacted with outrage, alleging that the man had a criminal record.