diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index 82990089ef..5b4fbebf7b 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -1109,6 +1109,14 @@ void libxl_mac_copy(libxl_ctx *ctx, libxl_mac *dst, const libxl_mac *src);
  */
 #define LIBXL_HAVE_DISK_BACKEND_FEATURES 1
 
+/*
+ * LIBXL_HAVE_VIF_BACKEND_FEATURES
+ *
+ * libxl_device_nic contains backend_features which can be used to control
+ * what features are exposed to guest vifs.
+ */
+#define LIBXL_HAVE_VIF_BACKEND_FEATURES 1
+
 typedef char **libxl_string_list;
 void libxl_string_list_dispose(libxl_string_list *sl);
 int libxl_string_list_length(const libxl_string_list *sl);
diff --git a/tools/libxl/libxl_9pfs.c b/tools/libxl/libxl_9pfs.c
index 9db887b5d8..3b80b358f4 100644
--- a/tools/libxl/libxl_9pfs.c
+++ b/tools/libxl/libxl_9pfs.c
@@ -42,7 +42,7 @@ static LIBXL_DEFINE_UPDATE_DEVID(p9, "9pfs")
 static int libxl__set_xenstore_p9(libxl__gc *gc, uint32_t domid,
                                   libxl_device_p9 *p9,
                                   flexarray_t *back, flexarray_t *front,
-                                  flexarray_t *ro_front)
+                                  flexarray_t *ro_front, flexarray_t *require)
 {
     flexarray_append_pair(back, "path", p9->path);
     flexarray_append_pair(back, "security_model", p9->security_model);
diff --git a/tools/libxl/libxl_console.c b/tools/libxl/libxl_console.c
index f40def1276..1c5a298750 100644
--- a/tools/libxl/libxl_console.c
+++ b/tools/libxl/libxl_console.c
@@ -730,7 +730,7 @@ static LIBXL_DEFINE_UPDATE_DEVID(vfb, "vfb")
 static int libxl__set_xenstore_vfb(libxl__gc *gc, uint32_t domid,
                                    libxl_device_vfb *vfb,
                                   flexarray_t *back, flexarray_t *front,
-                                  flexarray_t *ro_front)
+                                  flexarray_t *ro_front, flexarray_t *require)
 {
     flexarray_append_pair(back, "vnc",
                           libxl_defbool_val(vfb->vnc.enable) ? "1" : "0");
diff --git a/tools/libxl/libxl_device.c b/tools/libxl/libxl_device.c
index 05178fb480..87983e2ef9 100644
--- a/tools/libxl/libxl_device.c
+++ b/tools/libxl/libxl_device.c
@@ -1860,7 +1860,7 @@ void libxl__device_add_async(libxl__egc *egc, uint32_t domid,
                              libxl__ao_device *aodev)
 {
     STATE_AO_GC(aodev->ao);
-    flexarray_t *back;
+    flexarray_t *back, *require;
     flexarray_t *front, *ro_front;
     libxl__device *device;
     xs_transaction_t t = XBT_NULL;
@@ -1912,6 +1912,7 @@ void libxl__device_add_async(libxl__egc *egc, uint32_t domid,
     back = flexarray_make(gc, 16, 1);
     front = flexarray_make(gc, 16, 1);
     ro_front = flexarray_make(gc, 16, 1);
+    require = flexarray_make(gc, 16, 1);
 
     flexarray_append_pair(back, "frontend-id", GCSPRINTF("%d", domid));
     flexarray_append_pair(back, "online", "1");
@@ -1924,7 +1925,7 @@ void libxl__device_add_async(libxl__egc *egc, uint32_t domid,
                           GCSPRINTF("%d", XenbusStateInitialising));
 
     if (dt->set_xenstore_config)
-        dt->set_xenstore_config(gc, domid, type, back, front, ro_front);
+        dt->set_xenstore_config(gc, domid, type, back, front, ro_front, require);
 
     for (;;) {
         rc = libxl__xs_transaction_start(gc, &t);
@@ -1948,7 +1949,7 @@ void libxl__device_add_async(libxl__egc *egc, uint32_t domid,
                                   libxl__xs_kvs_of_flexarray(gc, back),
                                   libxl__xs_kvs_of_flexarray(gc, front),
                                   libxl__xs_kvs_of_flexarray(gc, ro_front),
-                                  NULL);
+                                  libxl__xs_kvs_of_flexarray(gc, require));
 
         rc = libxl__xs_transaction_commit(gc, &t);
         if (!rc) break;
@@ -1974,7 +1975,7 @@ out:
 int libxl__device_add(libxl__gc *gc, uint32_t domid,
                       const struct libxl_device_type *dt, void *type)
 {
-    flexarray_t *back;
+    flexarray_t *back, *require;
     flexarray_t *front, *ro_front;
     libxl__device *device;
     int rc;
@@ -1996,6 +1997,7 @@ int libxl__device_add(libxl__gc *gc, uint32_t domid,
     back = flexarray_make(gc, 16, 1);
     front = flexarray_make(gc, 16, 1);
     ro_front = flexarray_make(gc, 16, 1);
+    require = flexarray_make(gc, 16, 1);
 
     flexarray_append_pair(back, "frontend-id", GCSPRINTF("%d", domid));
     flexarray_append_pair(back, "online", "1");
@@ -2007,13 +2009,13 @@ int libxl__device_add(libxl__gc *gc, uint32_t domid,
                           GCSPRINTF("%d", XenbusStateInitialising));
 
     if (dt->set_xenstore_config)
-        dt->set_xenstore_config(gc, domid, type, back, front, ro_front);
+        dt->set_xenstore_config(gc, domid, type, back, front, ro_front, require);
 
     rc = libxl__device_generic_add(gc, XBT_NULL, device,
                                    libxl__xs_kvs_of_flexarray(gc, back),
                                    libxl__xs_kvs_of_flexarray(gc, front),
                                    libxl__xs_kvs_of_flexarray(gc, ro_front),
-                                   NULL);
+                                   libxl__xs_kvs_of_flexarray(gc, require));
     if (rc) goto out;
 
     rc = 0;
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 19c02e27a0..0881147d3c 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -3507,7 +3507,7 @@ typedef int (*device_from_xenstore_fn_t)(libxl__gc *, const char *,
                                          libxl_devid, void *);
 typedef int (*device_set_xenstore_config_fn_t)(libxl__gc *, uint32_t, void *,
                                                flexarray_t *, flexarray_t *,
-                                               flexarray_t *);
+                                               flexarray_t *, flexarray_t *);
 
 struct libxl_device_type {
     char *type;
diff --git a/tools/libxl/libxl_nic.c b/tools/libxl/libxl_nic.c
index 1e6ba6c78d..d67155d58d 100644
--- a/tools/libxl/libxl_nic.c
+++ b/tools/libxl/libxl_nic.c
@@ -143,7 +143,7 @@ static LIBXL_DEFINE_UPDATE_DEVID(nic, "vif")
 static int libxl__set_xenstore_nic(libxl__gc *gc, uint32_t domid,
                                    libxl_device_nic *nic,
                                    flexarray_t *back, flexarray_t *front,
-                                   flexarray_t *ro_front)
+                                   flexarray_t *ro_front, flexarray_t *require)
 {
     flexarray_grow(back, 2);
 
@@ -253,6 +253,17 @@ static int libxl__set_xenstore_nic(libxl__gc *gc, uint32_t domid,
     flexarray_append(front, GCSPRINTF(
                                     LIBXL_MAC_FMT, LIBXL_MAC_BYTES(nic->mac)));
 
+    if (nic->backend_features) {
+        libxl_key_value_list features = nic->backend_features;
+        int i;
+
+        for (i = 0; features[i] != NULL; i += 2) {
+            flexarray_append(require, libxl__strdup(gc, features[i]));
+            if (features[i+1])
+                flexarray_append(require, libxl__strdup(gc, features[i+1]));
+        }
+    }
+
     return 0;
 }
 
diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
index 949a797402..fba6127bbc 100644
--- a/tools/libxl/libxl_types.idl
+++ b/tools/libxl/libxl_types.idl
@@ -652,6 +652,7 @@ libxl_device_disk = Struct("device_disk", [
 libxl_device_nic = Struct("device_nic", [
     ("backend_domid", libxl_domid),
     ("backend_domname", string),
+    ("backend_features", libxl_key_value_list),
     ("devid", libxl_devid),
     ("mtu", integer),
     ("model", string),
diff --git a/tools/libxl/libxl_vdispl.c b/tools/libxl/libxl_vdispl.c
index e61ef2dfcd..3c266f4c73 100644
--- a/tools/libxl/libxl_vdispl.c
+++ b/tools/libxl/libxl_vdispl.c
@@ -76,7 +76,8 @@ static void libxl__device_vdispl_add(libxl__egc *egc, uint32_t domid,
 static int libxl__set_xenstore_vdispl(libxl__gc *gc, uint32_t domid,
                                       libxl_device_vdispl *vdispl,
                                       flexarray_t *back, flexarray_t *front,
-                                      flexarray_t *ro_front)
+                                      flexarray_t *ro_front,
+                                      flexarray_t *require)
 {
     int i;
 
diff --git a/tools/libxl/libxl_vtpm.c b/tools/libxl/libxl_vtpm.c
index 3f0c56349d..1fbb95c8aa 100644
--- a/tools/libxl/libxl_vtpm.c
+++ b/tools/libxl/libxl_vtpm.c
@@ -54,7 +54,7 @@ static LIBXL_DEFINE_UPDATE_DEVID(vtpm, "vtpm")
 static int libxl__set_xenstore_vtpm(libxl__gc *gc, uint32_t domid,
                                     libxl_device_vtpm *vtpm,
                                     flexarray_t *back, flexarray_t *front,
-                                    flexarray_t *ro_front)
+                                    flexarray_t *ro_front, flexarray_t *require)
 {
     flexarray_append_pair(back, "handle", GCSPRINTF("%d", vtpm->devid));
     flexarray_append_pair(back, "uuid",
