漢尼拔在阿爾卑斯山南曾與高盧人小有摩擦,但很快獲得了對羅馬統治不滿的高盧部族的熱烈歡迎,沿途實力破損的漢尼拔從高盧人中獲得了人馬補充。回軍意大利的西庇阿在波河流域遭遇了漢尼拔,漢尼拔大勝,西庇阿退守亞平寧山腳。這時派往非洲的森普羅尼烏斯軍也被急速召回,再與西庇阿軍會師之後,兩執政官聯軍進攻漢尼拔,結果大敗,4萬大軍僅餘一萬。此次大戰之後,羅馬人在北意的勢力不複存在,大批高盧人參加了漢尼拔的軍隊。

羅馬人在大敗之後,采取全力防守,派新選任的兩個執政官分守兩條大道以阻止漢尼拔南下。漢尼拔再次出人意料地穿越亞平寧山和沼澤地區,突然出現在羅馬大軍的身後,在特拉西美諾湖急速調回的弗拉米尼努斯大軍遭遇。漢尼拔設伏兵之計,大敗羅馬軍,執政官弗拉米尼努斯戰死,士兵陣亡1.5萬人,其餘大部分都成了漢尼拔的俘虜。當時另一執政官的軍隊距離遙遠,未能及時來援,漢尼拔得以繼續南下。但是,他沒有直接進攻羅馬,反而兵行東南,意圖煽動南意大利諸城反叛,但是沒能成功。

特拉西美諾湖戰役之後,羅馬的局勢岌岌可危,元老費邊(今譯法比烏斯)當選為獨裁官。老練的費邊采取拖延戰略與漢尼拔周旋,他盡量避免與漢尼拔正麵交鋒,而隻是迂回阻截漢尼拔的後路和側翼,還時常出動小股部隊進行騷擾。當時意大利各地都不歸順漢尼拔,他急於決戰,多次挑釁羅馬人進行大規模陣地戰,但費邊總是按兵不動。至公元前217年末,漢尼拔雖然洗劫了意大利許多城池,但沒有一個能夠牢固占有。

費邊獨裁官六個月任滿之後,兩執政官不再沿用拖延戰略,開始準備一場大規模的會戰。這正合漢尼拔心意,他將羅馬人誘至阿普裏亞,在那裏漢尼拔有較大的據點。公元前216年,在奧菲杜斯河的坎尼城附近,雙方進行了著名的“坎尼戰役”。據說羅馬軍人數大大超過漢尼拔軍,步兵比漢尼拔多一倍,但漢尼拔的一萬騎兵占有絕對優勢,漢尼拔便是發揮了自己騎兵多速度快的優勢,以6000人代價全殲了羅馬5萬大軍。在世界戰爭史上,坎尼戰役是一次非常有名的以少勝多的戰役。

坎尼大敗之後,羅馬一時眾叛親離,許多城邦開始背叛,而其餘則在靜觀其變。但羅馬還保有意大利中部和南部的多數城市,羅馬動用全國財富,擴充軍隊,到公元前212年基本恢複了元氣。漢尼拔則處境日危,他在南意能得的人馬補充有限,與北意的高盧人又聯結不上,母邦迦太基中的反對派又占了上風,不肯派兵支援。漢尼拔依然是尋求決戰,但羅馬采取了費邊的拖延戰略,漢尼拔無法速戰,而羅馬則愈戰愈勇,逐漸將漢尼拔擠到南意一角。

公元前207年,漢尼拔在西班牙的兄弟哈斯杜魯巴獲準援助漢尼拔,哈斯杜魯巴從西班牙出發越阿爾卑斯山抵達意大利,在行至翁布裏亞時與羅馬發生大戰,迦太基大敗,哈斯杜魯巴戰死。公元前206年底,羅馬名將西庇阿(通稱大西庇阿)把迦太基趕出了西班牙,這對漢尼拔的打擊不次於哈斯杜魯巴之死,因為西班牙畢竟是他的根據地。西庇阿因為在西班牙的不世之功,年僅30歲便破例被選為公元前205年的執政官。西庇阿認為隻有攻打迦太基本土,才能令迦太基召回漢尼拔,在群眾支持下,他獲得元老院的允許組織遠征北非。公元前203年的大平原一役,西庇阿以騎兵製勝,迦太基主力幾乎被全殲,此後不久迦太基求和,召回了漢尼拔。

據說,當漢尼拔及其弟瑪哥的部隊從意大利回來後,迦太基元老院主張再戰。公元前202年,雙方在迦太基南的紮瑪城附近舉行了一次大規模會戰,漢尼拔和西庇阿棋逢對手展開大戰,羅馬因得馬西尼撒的騎兵之助,取得了羅馬對漢尼拔的首次大勝,第二次布匿戰爭再次以羅馬的勝利結束。公元前201年的和約對迦太基來說極為苛刻,迦太基喪失了非洲以外的一切領土,除保留十艘巡邏艦,不再擁有海軍,不經羅馬許可不得與任何國家開戰,另外還負擔一萬塔蘭特的巨額賠款。