Pictures from the scene in the Puglia region showed both trains were on the same track about 15 kilometers (9 miles) south of the Adriatic Sea, apparently headed toward each other.
Images distributed by firefighters there showed the smashed remains of train cars and a large area of scattered, twisted metal at the impact site about 7 kilometers (4.3 miles) east of the city of Andria. More than 50 people were injured, Italian news agency ANSA reported.
One train was headed from Andria to Corato, while the other was coming in the opposite direction, ANSA reported.
At least 23 people were killed, and the number was expected to rise, a medical official at the scene told CNN on condition of anonymity. The official said 22 bodies had been pulled from the wreckage, and one person died in a hospital.
Italian Prime Minister Matteo Renzi called for an investigation into the collision.
“There will be a full inquiry to find out who is responsible for this crash, and what has happened,” Renzi told reporters Tuesday afternoon in Milan.
The rescue and recovery effort was ongoing, he added. A hospital in Andria was asking the public for blood donations for the injured through a local news website.
Renzi planned to visit the crash site on Tuesday evening, an Italian government website said.
The state-run rail company FS Group offered condolences and said both trains were operated by the private company Ferrotramviaria SpA, which runs commuter rail services in the area.
“The employees of the Italian FS Group are close to the victims’ families, the wounded and colleagues at Ferrotramviaria,” the FS Group said.
Details on what led to the crash weren’t immediately available.
The wreck happened in a relatively remote area. Local authorities took to social media to ask for any doctors and medics in the area to go to the crash site to help the injured.
“It’s not an area that’s easily accessible. The closest highway is miles away,” CNN contributor Barbie Nadeau said.