Witnesses said the fire started in the bus engine at the rear of the vehicle and quickly spread to its interior, according to spokesman Lewis Mejia, in broadcast comments on local TV channel Canal N.
The cause of the fire is under investigation, he added.
The fire started at the Fiori terminal in Lima’s northern San Martin de Porres district.
Lima's Mayor Jorge Muñoz said the bus burst into flames at a bus stop that authorities had banned just weeks ago because it was located next to an illegal shop that sells fuel.
"It appears that on the second floor of bus, where most of the victims were found, they were transporting fuel. That's a very serious matter," Muñoz told journalists in broadcast comments before visiting survivors at a local hospital.
Eight units of firefighters were deployed to put out the fire on the bus, which had been headed to the northern coastal city of Chiclayo, according to local media.
TV images showed the scorched remains of the vehicle surrounded by crowds of people in the district of San Martin de Porres on the outskirts of the capital.
#NOTICIAS840 Tragedia en Perú: Al menos 20 muertos deja incendio de un bus en Lima. La mayoría de las víctimas fallecieron en el primer piso del vehículo cuando intentaban escapar del fuego, pero solo algunos pasajeros pudieron salir por las ventanas. pic.twitter.com/y5D6eaz4Um
Authorities in Lima have repeatedly failed to rein in the city's so-called "informal" transportation system, a chaotic network of independent and unauthorized vans and buses used by millions of people every day.
Firefighters found that the bus lacked fire extinguishers and safety equipment, local media reported.
Muñoz vowed to punish the owners.
"They have defied a municipal order...I'm completely outraged," Muñoz said. "These people must be removed and criminal sanctions will be sought."