diff --git a/sys/include/net/gnrc/pktbuf.h b/sys/include/net/gnrc/pktbuf.h
index f9f29850b7b213851ff8a3d549e2537c53db9f9a..cf7a7a673639406769651866e2e207633e377ee8 100644
--- a/sys/include/net/gnrc/pktbuf.h
+++ b/sys/include/net/gnrc/pktbuf.h
@@ -298,6 +298,56 @@ gnrc_pktsnip_t *gnrc_pktbuf_reverse_snips(gnrc_pktsnip_t *pkt);
  */
 gnrc_pktsnip_t *gnrc_pktbuf_duplicate_upto(gnrc_pktsnip_t *pkt, gnrc_nettype_t type);
 
+/**
+ * @brief   Merge pktsnip chain to single pktsnip.
+ *
+ * Specifically it calls @ref gnrc_pktbuf_realloc_data() on @p pkt, then copies
+ * the data of all following packet snips into that reallocated space, and
+ * removes the packet snip the data was copied from afterwards.
+ *
+ *          Example:
+ *              Input:
+ *                                                                  buffer
+ *              +---------------------------+                      +------+
+ *              | size = 8                  | data       +-------->|      |
+ *              | type = NETTYPE_IPV6       |------------+         +------+
+ *              +---------------------------+                      .      .
+ *                    | next                                       .      .
+ *                    v                                            .      .
+ *              +---------------------------+                      +------+
+ *              | size = 40                 | data    +----------->|      |
+ *              | type = NETTYPE_UDP        |---------+            +------+
+ *              +---------------------------+                      .      .
+ *                    | next                                       .      .
+ *                    v
+ *              +---------------------------+                      +------+
+ *              | size = 14                 | data +-------------->|      |
+ *              | type = NETTYPE_UNDEF      |------+               +------+
+ *              +---------------------------+                      .      .
+ *
+ *
+ *              Output:
+ *                                                                  buffer
+ *              +---------------------------+                      +------+
+ *              | size = 62                 | data       +-------->|      |
+ *              | type = NETTYPE_IPV6       |------------+         |      |
+ *              +---------------------------+                      |      |
+ *                                                                 |      |
+ *                                                                 +------+
+ *                                                                 .      .
+ *
+ * @warning @p pkt needs to write protected before calling this function.
+ * @note    Packets in receive order need to call
+ *          @ref gnrc_pktbuf_reverse_snips() first to get the data in the
+ *          correct order.
+ *
+ * @param[in,out] pkt   The snip to merge.
+ *
+ * @return  0, on success
+ * @return  ENOMEM, if no space is left in the packet buffer.
+ */
+int gnrc_pktbuf_merge(gnrc_pktsnip_t *pkt);
+
 #ifdef DEVELHELP
 /**
  * @brief   Prints some statistics about the packet buffer to stdout.
diff --git a/sys/net/gnrc/pktbuf/gnrc_pktbuf.c b/sys/net/gnrc/pktbuf/gnrc_pktbuf.c
index 83e0a89e3121d9f6990b1136bd35d3ae63a37c5a..503e66c7b3806047fbc1fdecc152660ff64b58e6 100644
--- a/sys/net/gnrc/pktbuf/gnrc_pktbuf.c
+++ b/sys/net/gnrc/pktbuf/gnrc_pktbuf.c
@@ -109,5 +109,32 @@ gnrc_pktsnip_t *gnrc_pktbuf_reverse_snips(gnrc_pktsnip_t *pkt)
     return reversed;
 }
 
+int gnrc_pktbuf_merge(gnrc_pktsnip_t *pkt)
+{
+    size_t offset = pkt->size;
+    size_t size = gnrc_pkt_len(pkt);
+    int res = 0;
+
+    if (pkt->size == size) {
+        return res;
+    }
+
+    /* Re-allocate data */
+    res = gnrc_pktbuf_realloc_data(pkt, size);
+    if (res != 0) {
+        return res;
+    }
+
+    /* Copy data to new buffer */
+    for (gnrc_pktsnip_t *ptr = pkt->next; ptr != NULL; ptr = ptr->next) {
+        memcpy(((uint8_t *)pkt->data) + offset, ptr->data, ptr->size);
+        offset += ptr->size;
+    }
+
+    /* Release old pktsnips and data*/
+    gnrc_pktbuf_release(pkt->next);
+    pkt->next = NULL;
+    return res;
+}
 
 /** @} */