diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp
index 2e22523d7cb1..14a2089ea654 100644
--- a/src/libcamera/pipeline/uvcvideo.cpp
+++ b/src/libcamera/pipeline/uvcvideo.cpp
@@ -8,6 +8,7 @@
 #include <algorithm>
 
 #include <libcamera/camera.h>
+#include <libcamera/controls.h>
 #include <libcamera/request.h>
 #include <libcamera/stream.h>
 
@@ -16,6 +17,7 @@
 #include "media_device.h"
 #include "pipeline_handler.h"
 #include "utils.h"
+#include "v4l2_controls.h"
 #include "v4l2_videodevice.h"
 
 namespace libcamera {
@@ -71,6 +73,8 @@ public:
 	bool match(DeviceEnumerator *enumerator) override;
 
 private:
+	int processControls(UVCCameraData *data, Request *request);
+
 	UVCCameraData *cameraData(const Camera *camera)
 	{
 		return static_cast<UVCCameraData *>(
@@ -216,6 +220,39 @@ void PipelineHandlerUVC::stop(Camera *camera)
 	PipelineHandler::stop(camera);
 }
 
+int PipelineHandlerUVC::processControls(UVCCameraData *data, Request *request)
+{
+	V4L2Controls controls;
+
+	for (auto it : request->controls()) {
+		const ControlInfo &ci = it.first;
+		Value &value = it.second;
+
+		switch (ci.id()) {
+		case ManualBrightness:
+			LOG(UVC, Debug) << "Setting Brightness to : " << value;
+			controls.add(V4L2_CID_BRIGHTNESS, value.getInt());
+			break;
+		case ManualExposure:
+			LOG(UVC, Debug) << "Setting Exposure to : " << value;
+			controls.add(V4L2_CID_EXPOSURE_AUTO, 1);
+			controls.add(V4L2_CID_EXPOSURE_ABSOLUTE, value.getInt());
+			break;
+		case ManualGain:
+		default:
+			LOG(UVC, Debug) << "Unsupported control: "
+					<< ci.name() << " : " << value;
+			break;
+		}
+	}
+
+	int ret = data->video_->setControls(&controls);
+	if (ret)
+		LOG(UVC, Error) << "Failed to set controls";
+
+	return ret;
+}
+
 int PipelineHandlerUVC::queueRequest(Camera *camera, Request *request)
 {
 	UVCCameraData *data = cameraData(camera);
@@ -227,7 +264,11 @@ int PipelineHandlerUVC::queueRequest(Camera *camera, Request *request)
 		return -ENOENT;
 	}
 
-	int ret = data->video_->queueBuffer(buffer);
+	int ret = processControls(data, request);
+	if (ret < 0)
+		return ret;
+
+	ret = data->video_->queueBuffer(buffer);
 	if (ret < 0)
 		return ret;
 
