diff --git a/src/gstreamer/gstlibcamera-utils.cpp b/src/gstreamer/gstlibcamera-utils.cpp
index 750ec351..43ce75cb 100644
--- a/src/gstreamer/gstlibcamera-utils.cpp
+++ b/src/gstreamer/gstlibcamera-utils.cpp
@@ -553,3 +553,75 @@ gst_libcamera_get_camera_manager(int &ret)
 
 	return cm;
 }
+
+libcamera::Transform
+gst_libcamera_orientation_to_transform(GstVideoOrientationMethod orientation)
+{
+	switch (orientation) {
+	case GST_VIDEO_ORIENTATION_90R:
+		return Transform::Rot90;
+	case GST_VIDEO_ORIENTATION_180:
+		return Transform::Rot180;
+	case GST_VIDEO_ORIENTATION_90L:
+		return Transform::Rot270;
+	case GST_VIDEO_ORIENTATION_HORIZ:
+		return Transform::HFlip;
+	case GST_VIDEO_ORIENTATION_VERT:
+		return Transform::VFlip;
+	case GST_VIDEO_ORIENTATION_UL_LR:
+		return Transform::Transpose;
+	case GST_VIDEO_ORIENTATION_UR_LL:
+		return Transform::Rot180Transpose;
+	case GST_VIDEO_ORIENTATION_IDENTITY:
+	default:
+		return Transform::Identity;
+	}
+}
+
+GstVideoOrientationMethod
+gst_libcamera_transform_to_orientation(libcamera::Transform transform)
+{
+	switch (transform) {
+	case Transform::Rot90:
+		return GST_VIDEO_ORIENTATION_90R;
+	case Transform::Rot180:
+		return GST_VIDEO_ORIENTATION_180;
+	case Transform::Rot270:
+		return GST_VIDEO_ORIENTATION_90L;
+	case Transform::HFlip:
+		return GST_VIDEO_ORIENTATION_HORIZ;
+	case Transform::VFlip:
+		return GST_VIDEO_ORIENTATION_VERT;
+	case Transform::Transpose:
+		return GST_VIDEO_ORIENTATION_UL_LR;
+	case Transform::Rot180Transpose:
+		return GST_VIDEO_ORIENTATION_UR_LL;
+	case Transform::Identity:
+	default:
+		return GST_VIDEO_ORIENTATION_IDENTITY;
+	}
+}
+
+const char *
+gst_libcamera_transform_to_tag_string(libcamera::Transform transform)
+{
+	switch (transform) {
+	case Transform::Rot90:
+		return "rotate-90";
+	case Transform::Rot180:
+		return "rotate-180";
+	case Transform::Rot270:
+		return "rotate-270";
+	case Transform::HFlip:
+		return "flip-rotate-0";
+	case Transform::VFlip:
+		return "flip-rotate-180";
+	case Transform::Transpose:
+		return "flip-rotate-270";
+	case Transform::Rot180Transpose:
+		return "flip-rotate-90";
+	case Transform::Identity:
+	default:
+		return "rotate-0";
+	}
+}
diff --git a/src/gstreamer/gstlibcamera-utils.h b/src/gstreamer/gstlibcamera-utils.h
index fd304a8b..84d26c47 100644
--- a/src/gstreamer/gstlibcamera-utils.h
+++ b/src/gstreamer/gstlibcamera-utils.h
@@ -11,6 +11,7 @@
 #include <libcamera/camera_manager.h>
 #include <libcamera/controls.h>
 #include <libcamera/stream.h>
+#include <libcamera/transform.h>
 
 #include <gst/gst.h>
 #include <gst/video/video.h>
@@ -30,6 +31,10 @@ gboolean gst_task_resume(GstTask *task);
 #endif
 std::shared_ptr<libcamera::CameraManager> gst_libcamera_get_camera_manager(int &ret);
 
+libcamera::Transform gst_libcamera_orientation_to_transform(GstVideoOrientationMethod orientation);
+GstVideoOrientationMethod gst_libcamera_transform_to_orientation(libcamera::Transform transform);
+const char *gst_libcamera_transform_to_tag_string(libcamera::Transform transform);
+
 /**
  * \class GLibLocker
  * \brief A simple scoped mutex locker for GMutex
diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp
index 721b35c2..9d9437d0 100644
--- a/src/gstreamer/gstlibcamerasrc.cpp
+++ b/src/gstreamer/gstlibcamerasrc.cpp
@@ -147,6 +147,8 @@ struct _GstLibcameraSrc {
 
 	gchar *camera_name;
 
+	GstVideoOrientationMethod transform;
+
 	GstLibcameraSrcState *state;
 	GstLibcameraAllocator *allocator;
 	GstFlowCombiner *flow_combiner;
@@ -154,7 +156,9 @@ struct _GstLibcameraSrc {
 
 enum {
 	PROP_0,
-	PROP_CAMERA_NAME
+	PROP_CAMERA_NAME,
+	PROP_TRANSFORM,
+	PROP_LAST
 };
 
 G_DEFINE_TYPE_WITH_CODE(GstLibcameraSrc, gst_libcamera_src, GST_TYPE_ELEMENT,
@@ -461,6 +465,8 @@ gst_libcamera_src_task_enter(GstTask *task, [[maybe_unused]] GThread *thread,
 	GLibRecLocker lock(&self->stream_lock);
 	GstLibcameraSrcState *state = self->state;
 	GstFlowReturn flow_ret = GST_FLOW_OK;
+	libcamera::Transform tag_transform;
+	const char* tag_string;
 	gint ret;
 
 	g_autoptr(GstStructure) element_caps = gst_structure_new_empty("caps");
@@ -513,12 +519,27 @@ gst_libcamera_src_task_enter(GstTask *task, [[maybe_unused]] GThread *thread,
 	if (flow_ret != GST_FLOW_OK)
 		goto done;
 
+	state->config_->transform =
+		gst_libcamera_orientation_to_transform (self->transform);
+
 	/* Validate the configuration. */
 	if (state->config_->validate() == CameraConfiguration::Invalid) {
 		flow_ret = GST_FLOW_NOT_NEGOTIATED;
 		goto done;
 	}
 
+	tag_transform = (gst_libcamera_orientation_to_transform (self->transform) ^
+			 state->config_->transform);
+	tag_string = gst_libcamera_transform_to_tag_string(tag_transform);
+	for (gsize i = 0; i < state->srcpads_.size(); i++) {
+		GstPad *srcpad = state->srcpads_[i];
+		GstEvent *tag_event;
+
+		tag_event = gst_event_new_tag(gst_tag_list_new(GST_TAG_IMAGE_ORIENTATION,
+							       tag_string, NULL));
+		gst_pad_push_event (srcpad, tag_event);
+	}
+
 	ret = state->cam_->configure(state->config_.get());
 	if (ret) {
 		GST_ELEMENT_ERROR(self, RESOURCE, SETTINGS,
@@ -659,6 +680,11 @@ gst_libcamera_src_set_property(GObject *object, guint prop_id,
 		g_free(self->camera_name);
 		self->camera_name = g_value_dup_string(value);
 		break;
+	case PROP_TRANSFORM:
+		self->transform =
+			static_cast<GstVideoOrientationMethod>(
+				g_value_get_enum(value));
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
 		break;
@@ -676,6 +702,9 @@ gst_libcamera_src_get_property(GObject *object, guint prop_id, GValue *value,
 	case PROP_CAMERA_NAME:
 		g_value_set_string(value, self->camera_name);
 		break;
+        case PROP_TRANSFORM:
+                g_value_set_enum(value, self->transform);
+                break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
 		break;
@@ -845,4 +874,14 @@ gst_libcamera_src_class_init(GstLibcameraSrcClass *klass)
 						  | G_PARAM_CONSTRUCT
 						  | G_PARAM_READWRITE
 						  | G_PARAM_STATIC_STRINGS)));
+
+	g_object_class_install_property (object_class, PROP_TRANSFORM,
+		g_param_spec_enum ("transform", "Transform",
+				   "Request a transform (rotation and/or flip).",
+				   GST_TYPE_VIDEO_ORIENTATION_METHOD,
+				   GST_VIDEO_ORIENTATION_IDENTITY,
+				   (GParamFlags)(GST_PARAM_MUTABLE_READY
+						 | G_PARAM_CONSTRUCT
+						 | G_PARAM_READWRITE
+						 | G_PARAM_STATIC_STRINGS)));
 }
