diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h
index 5bb06584..5aa4bf69 100644
--- a/include/libcamera/camera.h
+++ b/include/libcamera/camera.h
@@ -88,6 +88,11 @@ class Camera final : public Object, public std::enable_shared_from_this<Camera>,
 	LIBCAMERA_DECLARE_PRIVATE()
 
 public:
+	enum RequestCompletionMode {
+		InSubmissionOrder,
+		Immediately,
+	};
+
 	static std::shared_ptr<Camera> create(std::unique_ptr<Private> d,
 					      const std::string &id,
 					      const std::set<Stream *> &streams);
@@ -101,6 +106,9 @@ public:
 	int acquire();
 	int release();
 
+	int setRequestCompletionMode(RequestCompletionMode order);
+	RequestCompletionMode requestCompletionMode() const;
+
 	const ControlInfoMap &controls() const;
 	const ControlList &properties() const;
 
diff --git a/include/libcamera/internal/camera.h b/include/libcamera/internal/camera.h
index 597426a6..68e8d952 100644
--- a/include/libcamera/internal/camera.h
+++ b/include/libcamera/internal/camera.h
@@ -33,6 +33,9 @@ public:
 
 	PipelineHandler *pipe() { return pipe_.get(); }
 
+	void setRequestCompletionMode(RequestCompletionMode mode);
+	RequestCompletionMode requestCompletionMode() const;
+
 	std::list<Request *> queuedRequests_;
 	ControlInfoMap controlInfo_;
 	ControlList properties_;
@@ -67,6 +70,7 @@ private:
 
 	bool disconnected_;
 	std::atomic<State> state_;
+	RequestCompletionMode requestCompletionMode_;
 
 	std::unique_ptr<CameraControlValidator> validator_;
 };
diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp
index 2a8ef60e..4d3523e2 100644
--- a/src/libcamera/camera.cpp
+++ b/src/libcamera/camera.cpp
@@ -435,7 +435,8 @@ CameraConfiguration::Status CameraConfiguration::validateColorSpaces(ColorSpaceF
  */
 Camera::Private::Private(PipelineHandler *pipe)
 	: requestSequence_(0), pipe_(pipe->shared_from_this()),
-	  disconnected_(false), state_(CameraAvailable)
+	  disconnected_(false), state_(CameraAvailable),
+	  requestCompletionMode_(Camera::InSubmissionOrder)
 {
 }
 
@@ -573,6 +574,28 @@ void Camera::Private::setState(State state)
 	state_.store(state, std::memory_order_release);
 }
 
+/**
+ * \brief Set the request completion mode
+ * \param[in] mode The RequestCompletionMode
+ *
+ * This function set the request completion mode.
+ * InSubmissionOrder is the default mode.
+ */
+void Camera::Private::setRequestCompletionMode(RequestCompletionMode mode)
+{
+	requestCompletionMode_ = mode;
+}
+
+/**
+ * \brief Get the request completion mode
+ *
+ * \return The current RequestCompletionMode.
+ */
+Camera::RequestCompletionMode Camera::Private::requestCompletionMode() const
+{
+	return requestCompletionMode_;
+}
+
 /**
  * \class Camera
  * \brief Camera device
@@ -702,6 +725,15 @@ std::shared_ptr<Camera> Camera::create(std::unique_ptr<Private> d,
 	return std::shared_ptr<Camera>(camera, Deleter());
 }
 
+/**
+ * \enum Camera::RequestCompletionMode
+ * \brief The mode of request completion behavior
+ * \var Camera::RequestCompletionMode::InSubmissionOrder
+ * \brief requestCompleted will be emited according to the request submission order
+ * \var Camera::RequestCompletionMode::Immediately
+ * \brief requestCompleted will be emited immediately when a request is completed.
+ */
+
 /**
  * \brief Retrieve the ID of the camera
  *
@@ -1237,6 +1269,40 @@ int Camera::stop()
 	return 0;
 }
 
+/**
+ * \brief Set the request completion mode
+ * \param[in] mode The RequestCompletionMode
+ *
+ * This function set the request completion mode.
+ * InSubmissionOrder is the default mode.
+ *
+ * \return 0 on success or a negative error code otherwise
+ * \retval -EACCES The camera is running so can't change the behavior
+ */
+int Camera::setRequestCompletionMode(RequestCompletionMode mode)
+{
+	Private *const d = _d();
+
+	int ret = d->isAccessAllowed(Private::CameraAvailable,
+				     Private::CameraConfigured);
+	if (ret < 0)
+		return -EACCES;
+
+	d->setRequestCompletionMode(mode);
+
+	return 0;
+}
+
+/**
+ * \brief Get the request completion mode
+ *
+ * \return The current RequestCompletionMode.
+ */
+Camera::RequestCompletionMode Camera::requestCompletionMode() const
+{
+	return _d()->requestCompletionMode();
+}
+
 /**
  * \brief Handle request completion and notify application
  * \param[in] request The request that has completed
diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp
index 67540533..7c180a8e 100644
--- a/src/libcamera/pipeline_handler.cpp
+++ b/src/libcamera/pipeline_handler.cpp
@@ -494,14 +494,20 @@ void PipelineHandler::completeRequest(Request *request)
 
 	Camera::Private *data = camera->_d();
 
-	while (!data->queuedRequests_.empty()) {
-		Request *req = data->queuedRequests_.front();
-		if (req->status() == Request::RequestPending)
-			break;
+	auto iter = data->queuedRequests_.begin();
+	while (iter != data->queuedRequests_.end()) {
+		if ((*iter)->status() != Request::RequestPending) {
+			ASSERT(!(*iter)->hasPendingBuffers());
+			camera->requestComplete((*iter));
+			iter = data->queuedRequests_.erase(iter);
+			continue;
+		}
 
-		ASSERT(!req->hasPendingBuffers());
-		data->queuedRequests_.pop_front();
-		camera->requestComplete(req);
+		/* Break at the pending result to reflect the submission order */
+		if (camera->requestCompletionMode() == Camera::InSubmissionOrder) {
+			break;
+		}
+		iter++;
 	}
 }
 
