diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h
index d3bae4cbee1e0cea..b5d4dfe4b1f6a586 100644
--- a/include/libcamera/camera.h
+++ b/include/libcamera/camera.h
@@ -25,6 +25,8 @@ public:
 
 	const std::string &name() const;
 
+	void disconnect();
+
 private:
 	explicit Camera(const std::string &name, class PipelineHandler *pipe);
 	~Camera();
diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp
index f198eb4978b12239..496fb1021c4fccf0 100644
--- a/src/libcamera/camera.cpp
+++ b/src/libcamera/camera.cpp
@@ -33,6 +33,8 @@
 
 namespace libcamera {
 
+LOG_DECLARE_CATEGORY(Camera)
+
 /**
  * \class Camera
  * \brief Camera device
@@ -86,6 +88,20 @@ const std::string &Camera::name() const
 	return name_;
 }
 
+/**
+ * \brief Disconnect the camera from the hardware
+ *
+ * When the underlying PipelineHandler is deleted as a result of the hardware
+ * being removed or un-pluged the Camera needs to be disconnected. The pipeline
+ * handler should when it detects that it's being removed notify all cameras it
+ * have created that they are now longer backed by any hardware.
+ */
+void Camera::disconnect()
+{
+	LOG(Camera, Debug) << "Disconnecting camera" << name_;
+	pipe_ = nullptr;
+}
+
 Camera::Camera(const std::string &name, class PipelineHandler *pipe)
 	: name_(name), pipe_(pipe)
 {
diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
index 19f73011f8b75438..c6106c538f071058 100644
--- a/src/libcamera/pipeline/ipu3/ipu3.cpp
+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
@@ -44,6 +44,9 @@ PipelineHandlerIPU3::PipelineHandlerIPU3()
 
 PipelineHandlerIPU3::~PipelineHandlerIPU3()
 {
+	for (const std::shared_ptr<Camera> &camera : cameras_)
+		camera->disconnect();
+
 	cameras_.clear();
 
 	if (cio2_)
diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp
index 2162824eb571fba7..a02f3671d22c5f79 100644
--- a/src/libcamera/pipeline/uvcvideo.cpp
+++ b/src/libcamera/pipeline/uvcvideo.cpp
@@ -34,8 +34,10 @@ PipelineHandlerUVC::PipelineHandlerUVC()
 
 PipelineHandlerUVC::~PipelineHandlerUVC()
 {
-	if (camera_)
+	if (camera_) {
+		camera_->disconnect();
 		camera_ = nullptr;
+	}
 
 	if (dev_)
 		dev_->release();
diff --git a/src/libcamera/pipeline/vimc.cpp b/src/libcamera/pipeline/vimc.cpp
index 373fc0ee5339f9ae..d732ac21cae1a84b 100644
--- a/src/libcamera/pipeline/vimc.cpp
+++ b/src/libcamera/pipeline/vimc.cpp
@@ -34,8 +34,10 @@ PipeHandlerVimc::PipeHandlerVimc()
 
 PipeHandlerVimc::~PipeHandlerVimc()
 {
-	if (camera_)
+	if (camera_) {
+		camera_->disconnect();
 		camera_ = nullptr;
+	}
 
 	if (dev_)
 		dev_->release();
