diff --git a/docs/man/xl.cfg.5.pod.in b/docs/man/xl.cfg.5.pod.in
index 0fba750815..592aad1d1e 100644
--- a/docs/man/xl.cfg.5.pod.in
+++ b/docs/man/xl.cfg.5.pod.in
@@ -1624,6 +1624,15 @@ are supported. This option is mandatory.
 The Virtio device with transport "pci" must be identified by its B<BDF>.
 See L<xl-pci-configuration(5)> for more details about the format for B<BDF>.
 
+=item B<backend_type=STRING>
+
+Specifies the software implementation of the backend implementation to use.
+This option doesn't affect the guest's view of the Virtio device.
+
+Both "qemu" and "standalone" are supported. The only difference is
+that for the former the toolstack assists with configuring and launching
+the device-model. If this option is missing, then "qemu" value will be used.
+
 =item B<grant_usage=BOOLEAN>
 
 If this option is B<true>, the Xen grants are always enabled.
diff --git a/tools/libs/light/libxl_types.idl b/tools/libs/light/libxl_types.idl
index a86c601994..13b8ade41c 100644
--- a/tools/libs/light/libxl_types.idl
+++ b/tools/libs/light/libxl_types.idl
@@ -284,6 +284,12 @@ libxl_virtio_transport = Enumeration("virtio_transport", [
     (2, "PCI"),
     ])
 
+libxl_virtio_backend = Enumeration("virtio_backend", [
+    (0, "UNKNOWN"),
+    (1, "QEMU"),
+    (2, "STANDALONE"),
+    ])
+
 libxl_passthrough = Enumeration("passthrough", [
     (0, "default"),
     (1, "disabled"),
@@ -778,6 +784,7 @@ libxl_device_vkb = Struct("device_vkb", [
 libxl_device_virtio = Struct("device_virtio", [
     ("backend_domid", libxl_domid),
     ("backend_domname", string),
+    ("backend_type", libxl_virtio_backend),
     ("type", string),
     ("u", KeyedUnion(None, libxl_virtio_transport, "transport",
               [("unknown", None),
diff --git a/tools/libs/light/libxl_virtio.c b/tools/libs/light/libxl_virtio.c
index 8062423c75..339a2006f0 100644
--- a/tools/libs/light/libxl_virtio.c
+++ b/tools/libs/light/libxl_virtio.c
@@ -32,9 +32,20 @@ static int libxl__device_virtio_setdefault(libxl__gc *gc, uint32_t domid,
     libxl_defbool_setdefault(&virtio->grant_usage,
                              virtio->backend_domid != LIBXL_TOOLSTACK_DOMID);
 
+    if (virtio->backend_type == LIBXL_VIRTIO_BACKEND_UNKNOWN)
+        virtio->backend_type = LIBXL_VIRTIO_BACKEND_QEMU;
+
     return 0;
 }
 
+static int libxl__device_virtio_dm_needed(void *e, unsigned domid)
+{
+    libxl_device_virtio *elem = e;
+
+    return elem->backend_type == LIBXL_VIRTIO_BACKEND_QEMU &&
+           elem->backend_domid == domid;
+}
+
 static int libxl__device_from_virtio(libxl__gc *gc, uint32_t domid,
                                      libxl_device_virtio *virtio,
                                      libxl__device *device)
@@ -55,7 +66,8 @@ static int libxl__set_xenstore_virtio(libxl__gc *gc, uint32_t domid,
                                       flexarray_t *back, flexarray_t *front,
                                       flexarray_t *ro_front)
 {
-    const char *transport = libxl_virtio_transport_to_string(virtio->transport);
+    const char *transport = libxl_virtio_transport_to_string(virtio->transport),
+               *backend = libxl_virtio_backend_to_string(virtio->backend_type);
 
     if (virtio->transport == LIBXL_VIRTIO_TRANSPORT_MMIO) {
         flexarray_append_pair(back, "irq", GCSPRINTF("%u", virtio->u.mmio.irq));
@@ -74,6 +86,7 @@ static int libxl__set_xenstore_virtio(libxl__gc *gc, uint32_t domid,
     }
     flexarray_append_pair(back, "type", GCSPRINTF("%s", virtio->type));
     flexarray_append_pair(back, "transport", GCSPRINTF("%s", transport));
+    flexarray_append_pair(back, "backend_type", GCSPRINTF("%s", backend));
     flexarray_append_pair(back, "grant_usage",
                           libxl_defbool_val(virtio->grant_usage) ? "1" : "0");
 
@@ -166,6 +179,19 @@ static int libxl__virtio_from_xenstore(libxl__gc *gc, const char *libxl_path,
         }
     }
 
+    tmp = NULL;
+    rc = libxl__xs_read_checked(gc, XBT_NULL,
+                                GCSPRINTF("%s/backend_type", be_path), &tmp);
+    if (rc) goto out;
+
+    if (tmp) {
+        rc = libxl_virtio_backend_from_string(tmp, &virtio->backend_type);
+        if (rc) {
+            LOG(ERROR, "Unable to parse xenstore node %s/backend_type", be_path);
+            goto out;
+        }
+    }
+
     tmp = NULL;
     rc = libxl__xs_read_checked(gc, XBT_NULL,
                                 GCSPRINTF("%s/grant_usage", be_path), &tmp);
@@ -200,6 +226,7 @@ static LIBXL_DEFINE_UPDATE_DEVID(virtio)
 #define libxl_device_virtio_compare NULL
 
 DEFINE_DEVICE_TYPE_STRUCT(virtio, VIRTIO, virtios,
+    .dm_needed = libxl__device_virtio_dm_needed,
     .set_xenstore_config = (device_set_xenstore_config_fn_t)
                            libxl__set_xenstore_virtio,
     .from_xenstore = (device_from_xenstore_fn_t)libxl__virtio_from_xenstore,
diff --git a/tools/xl/xl_parse.c b/tools/xl/xl_parse.c
index 4544ce2307..234cef5f7e 100644
--- a/tools/xl/xl_parse.c
+++ b/tools/xl/xl_parse.c
@@ -1215,6 +1215,9 @@ static int parse_virtio_config(libxl_device_virtio *virtio, char *token)
     } else if (MATCH_OPTION("transport", token, oparg)) {
         rc = libxl_virtio_transport_from_string(oparg, &virtio->transport);
         if (rc) return rc;
+    } else if (MATCH_OPTION("backend_type", token, oparg)) {
+        rc = libxl_virtio_backend_from_string(oparg, &virtio->backend_type);
+        if (rc) return rc;
     } else if (MATCH_OPTION("grant_usage", token, oparg)) {
         libxl_defbool_set(&virtio->grant_usage, strtoul(oparg, NULL, 0));
     } else if (MATCH_OPTION("bdf", token, oparg)) {
