diff --git a/src/libcamera/pipeline/virtual/virtual.cpp b/src/libcamera/pipeline/virtual/virtual.cpp
index 09583b4e..1d66a60e 100644
--- a/src/libcamera/pipeline/virtual/virtual.cpp
+++ b/src/libcamera/pipeline/virtual/virtual.cpp
@@ -9,12 +9,26 @@
 
 #include <libcamera/camera.h>
 
+#include "libcamera/internal/camera.h"
 #include "libcamera/internal/pipeline_handler.h"
 
 namespace libcamera {
 
 LOG_DEFINE_CATEGORY(VIRTUAL)
 
+class VirtualCameraData : public Camera::Private
+{
+public:
+	VirtualCameraData(PipelineHandler *pipe)
+		: Camera::Private(pipe)
+	{
+	}
+
+	~VirtualCameraData() = default;
+
+	Stream stream_;
+};
+
 class VirtualCameraConfiguration : public CameraConfiguration
 {
 public:
@@ -104,7 +118,15 @@ int PipelineHandlerVirtual::queueRequestDevice(Camera *camera, Request *request)
 bool PipelineHandlerVirtual::match(DeviceEnumerator *enumerator)
 {
 	(void)enumerator;
-	return false;
+
+	std::unique_ptr<VirtualCameraData> data = std::make_unique<VirtualCameraData>(this);
+	/* Create and register the camera. */
+	std::set<Stream *> streams{ &data->stream_ };
+	const std::string id = "Virtual0";
+	std::shared_ptr<Camera> camera = Camera::create(std::move(data), id, streams);
+	registerCamera(std::move(camera));
+
+	return false; // Prevent infinite loops for now
 }
 
 REGISTER_PIPELINE_HANDLER(PipelineHandlerVirtual)
