diff --git a/sys/include/net/gnrc/ipv6/nib.h b/sys/include/net/gnrc/ipv6/nib.h
index 00796e7fd4424dacbb8ef156b648b40053c5de35..3a4db2763f0264d98b82da7dfa3f2d72c24b1239 100644
--- a/sys/include/net/gnrc/ipv6/nib.h
+++ b/sys/include/net/gnrc/ipv6/nib.h
@@ -22,6 +22,7 @@
 #ifndef NET_GNRC_IPV6_NIB_H
 #define NET_GNRC_IPV6_NIB_H
 
+#include "net/gnrc/ipv6/nib/abr.h"
 #include "net/gnrc/ipv6/nib/nc.h"
 #include "net/gnrc/ipv6/nib/pl.h"
 
diff --git a/sys/include/net/gnrc/ipv6/nib/abr.h b/sys/include/net/gnrc/ipv6/nib/abr.h
new file mode 100644
index 0000000000000000000000000000000000000000..effb1ebd48df5ba4126fdb5cdf1930c87e7c2b09
--- /dev/null
+++ b/sys/include/net/gnrc/ipv6/nib/abr.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2017 Freie Universität Berlin
+ *
+ * This file is subject to the terms and conditions of the GNU Lesser
+ * General Public License v2.1. See the file LICENSE in the top level
+ * directory for more details.
+ */
+
+/**
+ * @defgroup    net_gnrc_ipv6_nib_abr   Authoritative border router list
+ * @ingroup     net_gnrc_ipv6_nib
+ * @brief       Authoritative border router list component of neighbor
+ *              information base
+ * @{
+ *
+ * @file
+ * @brief   Authoritative border router list definitions
+ *
+ * @author  Martine Lenders <m.lenders@fu-berlin.de>
+ */
+#ifndef NET_GNRC_IPV6_NIB_ABR_H
+#define NET_GNRC_IPV6_NIB_ABR_H
+
+#include "net/ipv6/addr.h"
+#include "net/gnrc/ipv6/nib/conf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if (GNRC_IPV6_NIB_CONF_6LBR && GNRC_IPV6_NIB_CONF_MULTIHOP_P6C) || defined(DOXYGEN)
+/**
+ * @brief   Adds the address of an authoritative border router to the NIB
+ *
+ * @param[in] addr  The address of an authoritative border router.
+ *
+ * @return  0 on success.
+ * @return  -ENOMEM, if no space is left in the neighbor cache.
+ */
+int gnrc_ipv6_nib_abr_add(const ipv6_addr_t *addr);
+
+/**
+ * @brief   Removes an authoritative border router from the NIB
+ *
+ * @param[in] addr  The address of an authoritative border router.
+ */
+void gnrc_ipv6_nib_abr_del(const ipv6_addr_t *addr);
+#endif  /* (GNRC_IPV6_NIB_CONF_6LBR && GNRC_IPV6_NIB_CONF_MULTIHOP_P6C) || defined(DOXYGEN) */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NET_GNRC_IPV6_NIB_ABR_H */
+/** @} */
diff --git a/sys/include/net/gnrc/ipv6/nib/conf.h b/sys/include/net/gnrc/ipv6/nib/conf.h
index adacc379080aaddc8322501721610818b2ef9056..4710ede5f5092903e92c6367afee7c49f25fab37 100644
--- a/sys/include/net/gnrc/ipv6/nib/conf.h
+++ b/sys/include/net/gnrc/ipv6/nib/conf.h
@@ -194,6 +194,15 @@ extern "C" {
 #define GNRC_IPV6_NIB_OFFL_NUMOF            (8)
 #endif
 
+#if GNRC_IPV6_NIB_CONF_MULTIHOP_P6C || defined(DOXYGEN)
+/**
+ * @brief   Number of authoritative border router entries in NIB
+ */
+#ifndef GNRC_IPV6_NIB_ABR_NUMOF
+#define GNRC_IPV6_NIB_ABR_NUMOF             (1)
+#endif
+#endif
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/sys/net/gnrc/network_layer/ipv6/nib/_nib-internal.c b/sys/net/gnrc/network_layer/ipv6/nib/_nib-internal.c
index 1593f940570667e1282892409fda9e226dbbac03..87049f245d65921b87aa24e083d0e116bad561f3 100644
--- a/sys/net/gnrc/network_layer/ipv6/nib/_nib-internal.c
+++ b/sys/net/gnrc/network_layer/ipv6/nib/_nib-internal.c
@@ -37,6 +37,10 @@ static _nib_offl_entry_t _dsts[GNRC_IPV6_NIB_OFFL_NUMOF];
 static _nib_dr_entry_t _def_routers[GNRC_IPV6_NIB_DEFAULT_ROUTER_NUMOF];
 static _nib_iface_t _nis[GNRC_NETIF_NUMOF];
 
+#if GNRC_IPV6_NIB_CONF_MULTIHOP_P6C
+static _nib_abr_entry_t _abrs[GNRC_IPV6_NIB_ABR_NUMOF];
+#endif
+
 #if ENABLE_DEBUG
 static char addr_str[IPV6_ADDR_MAX_STR_LEN];
 #endif
@@ -57,6 +61,9 @@ void _nib_init(void)
     memset(_def_routers, 0, sizeof(_def_routers));
     memset(_dsts, 0, sizeof(_dsts));
     memset(_nis, 0, sizeof(_nis));
+#if GNRC_IPV6_NIB_CONF_MULTIHOP_P6C
+    memset(_abrs, 0, sizeof(_abrs));
+#endif
 #endif
     evtimer_init_msg(&_nib_evtimer);
     /* TODO: load ABR information from persistent memory */
@@ -450,6 +457,13 @@ static inline bool _in_dsts(const _nib_offl_entry_t *dst)
     return (dst < (_dsts + GNRC_IPV6_NIB_OFFL_NUMOF));
 }
 
+#if GNRC_IPV6_NIB_CONF_MULTIHOP_P6C
+static inline bool _in_abrs(const _nib_abr_entry_t *abr)
+{
+    return (abr < (_abrs + GNRC_IPV6_NIB_ABR_NUMOF));
+}
+#endif
+
 void _nib_offl_clear(_nib_offl_entry_t *dst)
 {
     if (dst->next_hop != NULL) {
@@ -483,6 +497,131 @@ _nib_offl_entry_t *_nib_offl_iter(const _nib_offl_entry_t *last)
     return NULL;
 }
 
+void _nib_pl_remove(_nib_offl_entry_t *nib_offl)
+{
+    _nib_offl_remove(nib_offl, _PL);
+#if GNRC_IPV6_NIB_CONF_MULTIHOP_P6C
+    unsigned idx = nib_offl - _dsts;
+    if (idx < GNRC_IPV6_NIB_OFFL_NUMOF) {
+        for (_nib_abr_entry_t *abr = _abrs; _in_abrs(abr); abr++) {
+            if (bf_isset(abr->pfxs, idx)) {
+                DEBUG("nib: Removing prefix %s/%u ",
+                      ipv6_addr_to_str(addr_str, &nib_offl->pfx,
+                                       sizeof(addr_str)),
+                      nib_offl->pfx_len);
+                DEBUG("from border router %s\n",
+                      ipv6_addr_to_str(addr_str, &abr->addr, sizeof(addr_str)));
+                bf_unset(abr->pfxs, idx);
+            }
+        }
+    }
+#endif
+}
+
+#if GNRC_IPV6_NIB_CONF_MULTIHOP_P6C
+_nib_abr_entry_t *_nib_abr_add(const ipv6_addr_t *addr)
+{
+    _nib_abr_entry_t *abr = NULL;
+
+    assert(addr != NULL);
+    DEBUG("nib: Allocating authoritative border router entry (addr = %s)\n",
+          ipv6_addr_to_str(addr_str, addr, sizeof(addr_str)));
+    for (unsigned i = 0; i < GNRC_IPV6_NIB_ABR_NUMOF; i++) {
+        _nib_abr_entry_t *tmp = &_abrs[i];
+
+        if (ipv6_addr_equal(addr, &tmp->addr)) {
+            /* exact match */
+            DEBUG("  %p is an exact match\n", (void *)tmp);
+            return tmp;
+        }
+        if ((abr == NULL) && (ipv6_addr_is_unspecified(&tmp->addr))) {
+            abr = tmp;
+        }
+    }
+    if (abr != NULL) {
+        DEBUG("  using %p\n", (void *)abr);
+        memcpy(&abr->addr, addr, sizeof(abr->addr));
+    }
+#if ENABLE_DEBUG
+    else {
+        DEBUG("  NIB full\n");
+    }
+#endif
+    return abr;
+}
+
+void _nib_abr_remove(const ipv6_addr_t *addr)
+{
+    assert(addr != NULL);
+    DEBUG("nib: Removing border router %s\n", ipv6_addr_to_str(addr_str, addr,
+                                                               sizeof(addr_str)));
+    for (_nib_abr_entry_t *abr = _abrs; _in_abrs(abr); abr++) {
+        if (ipv6_addr_equal(addr, &abr->addr)) {
+            for (int i = 0; i < GNRC_IPV6_NIB_OFFL_NUMOF; i++) {
+                if (bf_isset(abr->pfxs, i)) {
+                    _nib_pl_remove(&_dsts[i]);
+                }
+            }
+#if MODULE_GNRC_SIXLOWPAN_CTX
+            for (int i = 0; i < GNRC_SIXLOWPAN_CTX_SIZE; i++) {
+                if (bf_isset(abr->ctxs, i)) {
+                    gnrc_sixlowpan_ctx_remove(i);
+                }
+            }
+#endif
+            memset(abr, 0, sizeof(_nib_abr_entry_t));
+        }
+    }
+}
+
+void _nib_abr_add_pfx(_nib_abr_entry_t *abr, const _nib_offl_entry_t *offl)
+{
+    assert((abr != NULL) && (offl != NULL) && (offl->mode & _PL));
+    unsigned idx = (unsigned)(_dsts - offl);
+
+    DEBUG("nib: Prefix %s/%u ",
+          ipv6_addr_to_str(addr_str, &offl->pfx, sizeof(addr_str)),
+          offl->pfx_len);
+    DEBUG("came from border router %s\n", ipv6_addr_to_str(addr_str, &abr->addr,
+                                                           sizeof(addr_str)));
+    if (idx < GNRC_IPV6_NIB_OFFL_NUMOF) {
+        bf_set(abr->pfxs, idx);
+    }
+}
+
+_nib_offl_entry_t *_nib_abr_iter_pfx(const _nib_abr_entry_t *abr,
+                                     const _nib_offl_entry_t *last)
+{
+    if ((last == NULL) ||
+        (((unsigned)(_dsts - last)) < GNRC_IPV6_NIB_OFFL_NUMOF)) {
+        /* we don't change `ptr`, so dropping const qualifier for now is okay */
+        _nib_offl_entry_t *ptr = (_nib_offl_entry_t *)last;
+
+        while ((ptr = _nib_offl_iter(ptr))) {
+            /* bf_isset() discards const, but doesn't change the array, so
+             * discarding it on purpose */
+            if ((ptr->mode & _PL) && (bf_isset((uint8_t *)abr->pfxs, ptr - _dsts))) {
+                return ptr;
+            }
+        }
+    }
+    return NULL;
+}
+
+_nib_abr_entry_t *_nib_abr_iter(const _nib_abr_entry_t *last)
+{
+    for (const _nib_abr_entry_t *abr = (last) ? (last + 1) : _abrs;
+         _in_abrs(abr); abr++) {
+        if (!ipv6_addr_is_unspecified(&abr->addr)) {
+            /* const modifier provided to assure internal consistency.
+             * Can now be discarded. */
+            return (_nib_abr_entry_t *)abr;
+        }
+    }
+    return NULL;
+}
+#endif  /* GNRC_IPV6_NIB_CONF_MULTIHOP_P6C */
+
 _nib_offl_entry_t *_nib_pl_add(unsigned iface,
                                const ipv6_addr_t *pfx,
                                unsigned pfx_len,
diff --git a/sys/net/gnrc/network_layer/ipv6/nib/_nib-internal.h b/sys/net/gnrc/network_layer/ipv6/nib/_nib-internal.h
index 0b96040b1490d56a61e78a14a4670323bfa8101b..3dd34e6b2fee304d66e78bc4530afcefbcb3fd7f 100644
--- a/sys/net/gnrc/network_layer/ipv6/nib/_nib-internal.h
+++ b/sys/net/gnrc/network_layer/ipv6/nib/_nib-internal.h
@@ -23,6 +23,7 @@
 #include <stdbool.h>
 #include <stdint.h>
 
+#include "bitfield.h"
 #include "evtimer_msg.h"
 #include "kernel_types.h"
 #include "mutex.h"
@@ -34,6 +35,7 @@
 #include "net/gnrc/ipv6/nib/nc.h"
 #include "net/gnrc/ipv6/nib/conf.h"
 #include "net/gnrc/pktqueue.h"
+#include "net/gnrc/sixlowpan/ctx.h"
 #include "net/ndp.h"
 #include "random.h"
 
@@ -221,6 +223,27 @@ typedef struct {
     uint8_t na_sent;
 } _nib_iface_t;
 
+/**
+ * @brief   Internal NIB-representation of the authoritative border router
+ *          for multihop prefix and 6LoWPAN context dissemination
+ */
+typedef struct {
+    ipv6_addr_t addr;               /**< The address of the border router */
+    uint32_t version;               /**< last received version of the info of
+                                     *   the _nib_abr_entry_t::addr */
+    evtimer_msg_event_t timeout;    /**< timeout of the information */
+    /**
+     * @brief   Bitfield marking the prefixes in the NIB's off-link entries
+     *          disseminated by _nib_abr_entry_t::addr
+     */
+    BITFIELD(pfxs, GNRC_IPV6_NIB_OFFL_NUMOF);
+    /**
+     * @brief   Bitfield marking the contexts disseminated by
+     *          _nib_abr_entry_t::addr
+     */
+    BITFIELD(ctxs, GNRC_SIXLOWPAN_CTX_SIZE);
+} _nib_abr_entry_t;
+
 /**
  * @brief   Mutex for locking the NIB
  */
@@ -598,11 +621,7 @@ _nib_offl_entry_t *_nib_pl_add(unsigned iface,
  *
  * Corresponding on-link entry is removed, too.
  */
-static inline void _nib_pl_remove(_nib_offl_entry_t *nib_offl)
-{
-    evtimer_del(&_nib_evtimer, &nib_offl->pfx_timeout.event);
-    _nib_offl_remove(nib_offl, _PL);
-}
+void _nib_pl_remove(_nib_offl_entry_t *nib_offl);
 
 #if GNRC_IPV6_NIB_CONF_ROUTER || DOXYGEN
 /**
@@ -648,6 +667,65 @@ static inline void _nib_ft_remove(_nib_offl_entry_t *nib_offl)
 }
 #endif  /* GNRC_IPV6_NIB_CONF_ROUTER */
 
+#if GNRC_IPV6_NIB_CONF_MULTIHOP_P6C || defined(DOXYGEN)
+/**
+ * @brief   Creates or gets an existing authoritative border router.
+ *
+ * @pre `addr != NULL`
+ *
+ * @param[in] addr  Address of the authoritative border router.
+ *
+ * @return  An authoritative border router entry, on success.
+ * @return  NULL, if no space is left.
+ */
+_nib_abr_entry_t *_nib_abr_add(const ipv6_addr_t *addr);
+
+/**
+ * @brief   Removes an authoritative border router
+ *
+ * @pre `addr != NULL`
+ *
+ * @param[in] addr  Address of the authoritative border router.
+ */
+void _nib_abr_remove(const ipv6_addr_t *addr);
+
+/**
+ * @brief   Adds a prefix to the managed prefix of the authoritative border
+ *          router
+ *
+ * @pre `(abr != NULL) && (offl != NULL) && (offl->mode & _PL)`
+ *
+ * @param[in] abr   The border router.
+ * @param[in] offl  The prefix to add.
+ */
+void _nib_abr_add_pfx(_nib_abr_entry_t *abr, const _nib_offl_entry_t *offl);
+
+/**
+ * @brief   Iterates over an authoritative border router's prefixes
+ *
+ * @pre `(abr != NULL)`
+ *
+ * @param[in] abr   The border router
+ * @param[in] last  Last prefix (NULL to start)
+ *
+ * @return  entry after @p last.
+ * @return  NULL, if @p last is the last prefix of @p abr or if @p last
+ *          wasn't in NIB (and != NULL).
+ */
+_nib_offl_entry_t *_nib_abr_iter_pfx(const _nib_abr_entry_t *abr,
+                                     const _nib_offl_entry_t *last);
+
+/**
+ * @brief   Iterates over authoritative border router entries
+ *
+ * @param[in] last  Last entry (NULL to start).
+ *
+ * @return  entry after @p last.
+ * @return  NULL, if @p last is the last ABR in the NIB.
+ */
+_nib_abr_entry_t *_nib_abr_iter(const _nib_abr_entry_t *last);
+#endif
+
 /**
  * @brief   Gets (or creates if it not exists) interface information for
  *          neighbor discovery
diff --git a/sys/net/gnrc/network_layer/ipv6/nib/nib_abr.c b/sys/net/gnrc/network_layer/ipv6/nib/nib_abr.c
new file mode 100644
index 0000000000000000000000000000000000000000..5c926b7abe74afd614a25e9277347ff06f4992d3
--- /dev/null
+++ b/sys/net/gnrc/network_layer/ipv6/nib/nib_abr.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2017 Freie Universität Berlin
+ *
+ * This file is subject to the terms and conditions of the GNU Lesser
+ * General Public License v2.1. See the file LICENSE in the top level
+ * directory for more details.
+ */
+
+/**
+ * @{
+ *
+ * @file
+ * @author  Martine Lenders <mlenders@inf.fu-berlin.de>
+ */
+
+#include "net/gnrc/ipv6/nib/abr.h"
+
+#include "_nib-internal.h"
+
+#if GNRC_IPV6_NIB_CONF_6LBR && GNRC_IPV6_NIB_CONF_MULTIHOP_P6C
+int gnrc_ipv6_nib_abr_add(const ipv6_addr_t *addr)
+{
+    _nib_abr_entry_t *abr;
+    _nib_offl_entry_t *offl = NULL;
+
+    mutex_lock(&_nib_mutex);
+    if ((abr = _nib_abr_add(addr)) == NULL) {
+        mutex_unlock(&_nib_mutex);
+        return -ENOMEM;
+    }
+    while ((offl = _nib_offl_iter(offl))) {
+        if (offl->mode & _PL) {
+            _nib_abr_add_pfx(abr, offl);
+        }
+    }
+#ifdef MODULE_GNRC_SIXLOWPAN_CTX    /* included optionally for NIB testing */
+    for (uint8_t id = 0; id < GNRC_SIXLOWPAN_CTX_SIZE; id++) {
+        if (gnrc_sixlowpan_ctx_lookup_id(id) != NULL) {
+            bf_set(abr->ctxs, id);
+        }
+    }
+#endif
+    mutex_unlock(&_nib_mutex);
+    return 0;
+}
+
+void gnrc_ipv6_nib_abr_del(const ipv6_addr_t *addr)
+{
+    mutex_lock(&_nib_mutex);
+    _nib_abr_remove(addr);
+    mutex_unlock(&_nib_mutex);
+}
+#else
+typedef int dont_be_pedantic;
+#endif
+
+/** @} */