Annibale era un brillante generale e aveva capito che Cartagine non avrebbe mai potuto sconfiggere Roma finché questa avesse avuto accesso a tutte le risorse dell'Italia. Per vincere doveva interrompere la cooperazione romana con tutte le altre città italiane, e per farlo doveva invadere la penisola. Dal momento che la flotta romana dominava ormai il mare, fu costretto a percorrere la lunga strada via terra. Questo terribile viaggio di sei mesi incluse anche il passaggio delle Alpi. Nel 218 a.C. Annibale arrivò in Italia con 20.000 soldati a piedi e circa 5.000 cavalieri.
Nel 217 sconfisse un esercito romano di circa 15.000 soldati, distruggendolo quasi completamente. Si spostò verso sud, sperando di provocare sollevazioni nelle città italiane soggette a Roma, ma solo poche si unirono alla causa cartaginese. Le sue forze si spostavano sul territorio senza molto effetto.
Nel 216 a.C. i Romani si erano riorganizzati e avevano messo in campo contro Annibale un enorme esercito, che secondo le fonti comprendeva dai 50.000 agli 80.000 soldati. Le due forze si scontrarono a Canne. Annibale lasciò che il centro del suo schieramento arretrasse davanti all'attacco romano, ma poi sferrò un violento attacco con la cavalleria ai fianchi dell'esercito nemico, che non era protetto adeguatamente. Le forze romane si ritrovarono circondate e attaccate da tutti i lati. Poco dopo Annibale aveva distrutto un'altra armata nemica, questa volta molto più potente. Questo trionfo demoralizzò completamente i Romani. La conseguenza più importante della vittoria di Annibale fu la dimostrazione che Roma poteva essere sconfitta; quindi un gran numero di città del sud dell'Italia voltò le spalle a Roma e corse in aiuto di Cartagine.
Le forze di Annibale ora erano notevolmente incrementate, ma d'altro canto il generale cartaginese doveva occuparsi della protezione di molte città alleate. Roma aveva perso un grande esercito e buona parte dei suoi possedimenti nel sud, però aveva ancora il nord dell'Italia, per non parlare del controllo navale del Mediterraneo. La guerra degenerò in una situazione di stallo.
Nel 207 a.C. Asdrubale, il fratello di Annibale, emulò la sua storica marcia e portò un secondo esercito in Italia attraverso le Alpi. Il piano era di scendere in Italia centrale lungo l'Adriatico, lontano da Roma, unirsi al fratello e lanciare un attacco finale al cuore della repubblica. Roma riuscì a mettere insieme un altro esercito e le due forze si incontrarono sul fiume Metauro. Ispirandosi alla tattica dello stesso Annibale, il generale romano Gaio Claudio Nerone riuscì ad accerchiare Asdrubale, tagliandogli la strada per la ritirata. La maggior parte dell'esercito cartaginese fu massacrato e lo stesso Asdrubale finì ucciso. La sua testa, spiccata dal corpo, fu lanciata nel campo di Annibale. Questa disfatta cambiò le sorti dell'invasione. Annibale rimase nell'area ancora per anni, ma non fu più in grado di sfidare Roma in Italia.
Nel frattempo, il grande generale romano Scipione aveva conquistato la maggior parte della Spagna cartaginese. Nonostante la presenza di Annibale nell'Italia del sud, Scipione convinse il Senato a intraprendere l'invasione dell'Africa. Nel 204 salpò per attraversare il Mediterraneo. Sconfisse una prima volta i Cartaginesi, e poi di nuovo l'anno successivo. Nel 202 a.C. affrontò finalmente Annibale, che era stato richiamato in patria per affrontare la crisi. Sebbene l'esercito cartaginese fosse di poco superiore numericamente, i soldati di Scipione erano veterani e la sua cavalleria era migliore. L'esercito di Annibale fu preso sul fianco e distrutto quasi completamente. Prostrata e ormai indifesa, Cartagine chiese la pace. Roma la privò di tutti i possedimenti che ancora le rimanevano in Spagna e nelle isole e la colpì duramente con l'imposizione di 10.000 talenti come riparazione di guerra (un'enorme quantità d'oro).