diff --git a/doc/bird.sgml b/doc/bird.sgml
index c4d2c49b..e3e46d6e 100644
--- a/doc/bird.sgml
+++ b/doc/bird.sgml
@@ -1716,6 +1716,11 @@ Common route attributes are:
 	are merged to one ECMP route during export to the Kernel protocol
 	(with active <ref id="krt-merge-paths" name="marge paths"> option).
 
+	<tag><label id="rta-label"><m/int/ label</tag>
+	MPLS label attached to route. Reading returns the label value and setting
+	it sets it to the start of the label array. Only one label per route supported
+	right now. This can be extended to support stacked labels. 
+
 	<tag><label id="rta-igp-metric"><m/int/ igp_metric</tag>
 	The optional attribute that can be used to specify a distance to the
 	network for routes that do not have a native protocol metric attribute
diff --git a/filter/config.Y b/filter/config.Y
index 5cd52e40..2578b96e 100644
--- a/filter/config.Y
+++ b/filter/config.Y
@@ -278,7 +278,7 @@ CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN,
 	SET, STRING, BGPMASK, BGPPATH, CLIST, ECLIST, LCLIST,
 	IF, THEN, ELSE, CASE,
 	TRUE, FALSE, RT, RO, UNKNOWN, GENERIC,
-	FROM, GW, NET, MASK, PROTO, SOURCE, SCOPE, DEST, IFNAME, IFINDEX, WEIGHT,
+	FROM, GW, NET, MASK, PROTO, SOURCE, SCOPE, DEST, IFNAME, IFINDEX, WEIGHT, MPLS,
 	PREFERENCE,
 	ROA_CHECK, ASN, SRC, DST,
 	IS_V4, IS_V6,
@@ -751,6 +751,7 @@ static_attr:
  | IFNAME  { $$ = f_new_static_attr(T_STRING,     SA_IFNAME,	0); }
  | IFINDEX { $$ = f_new_static_attr(T_INT,        SA_IFINDEX,	1); }
  | WEIGHT  { $$ = f_new_static_attr(T_INT,        SA_WEIGHT,	0); }
+ | MPLS    { $$ = f_new_static_attr(T_INT,        SA_MPLS,	0); }
  ;
 
 term:
diff --git a/filter/data.h b/filter/data.h
index 61cdb43e..e7cb56eb 100644
--- a/filter/data.h
+++ b/filter/data.h
@@ -100,6 +100,7 @@ enum f_sa_code {
   SA_IFNAME,
   SA_IFINDEX,
   SA_WEIGHT,
+  SA_MPLS,
 } PACKED;
 
 /* Static attribute definition (members of struct rta) */
diff --git a/filter/f-inst.c b/filter/f-inst.c
index 1378fe4a..3f58e180 100644
--- a/filter/f-inst.c
+++ b/filter/f-inst.c
@@ -533,6 +533,7 @@
       case SA_IFNAME:	RESULT(sa.f_type, s, rta->nh.iface ? rta->nh.iface->name : ""); break;
       case SA_IFINDEX:	RESULT(sa.f_type, i, rta->nh.iface ? rta->nh.iface->index : 0); break;
       case SA_WEIGHT:	RESULT(sa.f_type, i, rta->nh.weight + 1); break;
+      case SA_MPLS: 	RESULT(sa.f_type, i, rta->nh.label[0]); break;
 
       default:
 	bug("Invalid static attribute access (%u/%u)", sa.f_type, sa.sa_code);
@@ -569,6 +570,7 @@
 	  rta->nh.iface = n->iface;
 	  rta->nh.next = NULL;
 	  rta->hostentry = NULL;
+	  rta->nh.labels = 0;
 	}
 	break;
 
@@ -587,6 +589,7 @@
 	  rta->nh.iface = NULL;
 	  rta->nh.next = NULL;
 	  rta->hostentry = NULL;
+	  rta->nh.labels = 0;
 	}
 	break;
 
@@ -601,6 +604,14 @@
 	  rta->nh.iface = ifa;
 	  rta->nh.next = NULL;
 	  rta->hostentry = NULL;
+	  rta->nh.labels = 0;
+	}
+	break;
+
+      case SA_MPLS:
+	{
+	  rta->nh.label[0] = v1.val.i;
+	  rta->nh.labels = 1;
 	}
 	break;
 
