diff --git a/test/validation/packet/packet.c b/test/validation/packet/packet.c
index dc40cfb..fbfb260 100644
--- a/test/validation/packet/packet.c
+++ b/test/validation/packet/packet.c
@@ -380,19 +380,48 @@ static void _verify_headroom_shift(odp_packet_t packet,
 	void *data;
 	char *data_orig = odp_packet_data(packet);
 	char *head_orig = odp_packet_head(packet);
+	odp_packet_t out_pkt;
+	uint32_t seg_len;
+	int extended;
 
-	if (shift >= 0)
-		data = odp_packet_push_head(packet, shift);
-	else
-		data = odp_packet_pull_head(packet, -shift);
+	if (shift >= 0) {
+		if (abs(shift) <= room) {
+			data = odp_packet_push_head(packet, shift);
+			extended = 0;
+		} else {
+			data = odp_packet_extend_head(packet, shift,
+						      &out_pkt, &seg_len);
+			extended = 1;
+		}
+	} else {
+		if (abs(shift) <= seg_data_len) {
+			data = odp_packet_pull_head(packet, -shift);
+			extended = 0;
+		} else {
+			data = odp_packet_trunc_head(packet, -shift,
+						     &out_pkt, &seg_len);
+			extended = 1;
+		}
+	}
 
 	CU_ASSERT_PTR_NOT_NULL(data);
-	CU_ASSERT(odp_packet_headroom(packet) == room - shift);
-	CU_ASSERT(odp_packet_seg_len(packet) == seg_data_len + shift);
+	if (extended) {
+		if (shift >= 0) {
+			CU_ASSERT(odp_packet_seg_len(packet) == shift - room);
+		} else {
+			CU_ASSERT(odp_packet_headroom(packet) >=
+				  abs(shift) - seg_data_len);
+		}
+		CU_ASSERT(odp_packet_head(packet) != head_orig);
+	} else {
+		CU_ASSERT(odp_packet_headroom(packet) == room - shift);
+		CU_ASSERT(odp_packet_seg_len(packet) == seg_data_len + shift);
+		CU_ASSERT(data == data_orig - shift);
+		CU_ASSERT(odp_packet_head(packet) == head_orig);
+	}
+
 	CU_ASSERT(odp_packet_len(packet) == pkt_data_len + shift);
 	CU_ASSERT(odp_packet_data(packet) == data);
-	CU_ASSERT(odp_packet_head(packet) == head_orig);
-	CU_ASSERT(data == data_orig - shift);
 }
 
 void packet_test_headroom(void)
@@ -417,16 +446,25 @@ void packet_test_headroom(void)
 	_verify_headroom_shift(pkt, push_val + pull_val);
 	_verify_headroom_shift(pkt, -push_val);
 	_verify_headroom_shift(pkt, 0);
+
+	if (segmentation_supported) {
+		push_val = room * 2;
+		_verify_headroom_shift(pkt, push_val);
+		_verify_headroom_shift(pkt, 0);
+		_verify_headroom_shift(pkt, -push_val);
+	}
 }
 
 static void _verify_tailroom_shift(odp_packet_t pkt,
 				   int shift)
 {
 	odp_packet_seg_t seg;
+	odp_packet_t out_pkt;
 	uint32_t room;
-	uint32_t seg_data_len, pkt_data_len;
+	uint32_t seg_data_len, pkt_data_len, seg_len;
 	void *tail;
 	char *tail_orig;
+	int extended;
 
 	room = odp_packet_tailroom(pkt);
 	pkt_data_len = odp_packet_len(pkt);
@@ -443,27 +481,60 @@ static void _verify_tailroom_shift(odp_packet_t pkt,
 		l3_off = odp_packet_l3_offset(pkt);
 		l4_off = odp_packet_l4_offset(pkt);
 
-		tail = odp_packet_push_tail(pkt, shift);
+		if (abs(shift) <= room) {
+			tail = odp_packet_push_tail(pkt, shift);
+			extended = 0;
+		} else {
+			tail = odp_packet_extend_tail(pkt, shift,
+						      &out_pkt, &seg_len);
+			extended = 1;
+		}
 
 		CU_ASSERT(l2_off == odp_packet_l2_offset(pkt));
 		CU_ASSERT(l3_off == odp_packet_l3_offset(pkt));
 		CU_ASSERT(l4_off == odp_packet_l4_offset(pkt));
 	} else {
-		tail = odp_packet_pull_tail(pkt, -shift);
+		if (abs(shift) <=
+		    odp_packet_seg_data_len(pkt, odp_packet_last_seg(pkt))) {
+			    tail = odp_packet_pull_tail(pkt, -shift);
+			    extended = 0;
+		    } else {
+			    tail = odp_packet_trunc_tail(pkt, -shift,
+							 &out_pkt, &seg_len);
+			    extended = 1;
+		    }
 	}
 
 	CU_ASSERT_PTR_NOT_NULL(tail);
-	CU_ASSERT(odp_packet_seg_data_len(pkt, seg) == seg_data_len + shift);
+	if (extended) {
+		CU_ASSERT(odp_packet_last_seg(pkt) != seg);
+		seg = odp_packet_last_seg(pkt);
+		if (shift > 0) {
+			CU_ASSERT(odp_packet_seg_data_len(pkt, seg) ==
+				  shift - room);
+		} else {
+			CU_ASSERT(odp_packet_tailroom(pkt) >=
+				  abs(shift) - seg_data_len);
+		}
+
+	} else {
+		CU_ASSERT(odp_packet_seg_data_len(pkt, seg) ==
+			  seg_data_len + shift);
+		CU_ASSERT(odp_packet_tailroom(pkt) == room - shift);
+		if (room == 0 || (room - shift) == 0)
+			return;
+		if (shift >= 0) {
+			CU_ASSERT(odp_packet_tail(pkt) == tail_orig + shift);
+		} else {
+			CU_ASSERT(tail == tail_orig + shift);
+		}
+	}
+
 	CU_ASSERT(odp_packet_len(pkt) == pkt_data_len + shift);
-	CU_ASSERT(odp_packet_tailroom(pkt) == room - shift);
-	if (room == 0 || (room - shift) == 0)
-		return;
 	if (shift >= 0) {
-		CU_ASSERT(odp_packet_tail(pkt) == tail_orig + shift);
 		CU_ASSERT(tail == tail_orig);
 	} else {
 		CU_ASSERT(odp_packet_tail(pkt) == tail);
-		CU_ASSERT(tail == tail_orig + shift);
 	}
 }
 
@@ -492,6 +563,12 @@ void packet_test_tailroom(void)
 	_verify_tailroom_shift(pkt, push_val + pull_val);
 	_verify_tailroom_shift(pkt, -push_val);
 	_verify_tailroom_shift(pkt, 0);
+
+	if (segmentation_supported) {
+		_verify_tailroom_shift(pkt, pull_val);
+		_verify_tailroom_shift(pkt, 0);
+		_verify_tailroom_shift(pkt, -pull_val);
+	}
 }
 
 void packet_test_segments(void)
@@ -869,13 +946,13 @@ odp_testinfo_t packet_suite[] = {
 	ODP_TEST_INFO(packet_test_alloc_segmented),
 	ODP_TEST_INFO(packet_test_basic_metadata),
 	ODP_TEST_INFO(packet_test_debug),
+	ODP_TEST_INFO(packet_test_segments),
 	ODP_TEST_INFO(packet_test_length),
 	ODP_TEST_INFO(packet_test_headroom),
 	ODP_TEST_INFO(packet_test_tailroom),
 	ODP_TEST_INFO(packet_test_context),
 	ODP_TEST_INFO(packet_test_event_conversion),
 	ODP_TEST_INFO(packet_test_layer_offsets),
-	ODP_TEST_INFO(packet_test_segments),
 	ODP_TEST_INFO(packet_test_segment_last),
 	ODP_TEST_INFO(packet_test_in_flags),
 	ODP_TEST_INFO(packet_test_error_flags),
