diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
index c2064a35688b..81584169a80f 100644
--- a/tools/testing/selftests/Makefile
+++ b/tools/testing/selftests/Makefile
@@ -49,6 +49,7 @@ TARGETS += net/forwarding
 TARGETS += net/mptcp
 TARGETS += netfilter
 TARGETS += nsfs
+TARGETS += pci
 TARGETS += pidfd
 TARGETS += pid_namespace
 TARGETS += powerpc
diff --git a/tools/testing/selftests/pci/.gitignore b/tools/testing/selftests/pci/.gitignore
new file mode 100644
index 000000000000..db01411b8200
--- /dev/null
+++ b/tools/testing/selftests/pci/.gitignore
@@ -0,0 +1 @@
+pci-selftest
diff --git a/tools/testing/selftests/pci/Makefile b/tools/testing/selftests/pci/Makefile
new file mode 100644
index 000000000000..76b7725a45ae
--- /dev/null
+++ b/tools/testing/selftests/pci/Makefile
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0
+CFLAGS += -O2 -Wl,-no-as-needed -Wall
+LDFLAGS += -lrt -lpthread -lm
+
+TEST_GEN_PROGS = pci-selftest
+
+include ../lib.mk
diff --git a/tools/testing/selftests/pci/pci-selftest.c b/tools/testing/selftests/pci/pci-selftest.c
new file mode 100644
index 000000000000..73e8f3eb1982
--- /dev/null
+++ b/tools/testing/selftests/pci/pci-selftest.c
@@ -0,0 +1,167 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PCI Endpoint Driver Test Program
+ *
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *             https://www.samsung.com
+ * Author: Aman Gupta <aman1.gupta@samsung.com>
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+
+#include "../kselftest_harness.h"
+
+#define PCITEST_BAR		_IO('P', 0x1)
+#define PCITEST_LEGACY_IRQ	_IO('P', 0x2)
+#define PCITEST_MSI		_IOW('P', 0x3, int)
+#define PCITEST_WRITE		_IOW('P', 0x4, unsigned long)
+#define PCITEST_READ		_IOW('P', 0x5, unsigned long)
+#define PCITEST_COPY		_IOW('P', 0x6, unsigned long)
+#define PCITEST_MSIX		_IOW('P', 0x7, int)
+#define PCITEST_SET_IRQTYPE	_IOW('P', 0x8, int)
+#define PCITEST_GET_IRQTYPE	_IO('P', 0x9)
+#define PCITEST_CLEAR_IRQ	_IO('P', 0x10)
+
+static char *test_device = "/dev/pci-endpoint-test.0";
+
+struct xfer_param {
+	unsigned long size;
+	unsigned char flag;
+	};
+
+FIXTURE(device)
+{
+	int fd;
+};
+
+FIXTURE_SETUP(device)
+{
+
+	self->fd = open(test_device, O_RDWR);
+
+	ASSERT_NE(-1, self->fd) {
+		TH_LOG("Can't open PCI Endpoint Test device\n");
+	}
+}
+
+FIXTURE_TEARDOWN(device)
+{
+	close(self->fd);
+}
+
+TEST_F(device, BAR_TEST)
+{
+	int ret = -EINVAL;
+	int final = 0;
+
+	for (int i = 0; i <= 5; i++) {
+		ret = ioctl(self->fd, PCITEST_BAR, i);
+
+		EXPECT_EQ(1, ret) {
+			TH_LOG("TEST FAILED FOR BAR %d\n", i);
+			final++;
+		}
+	}
+
+	ASSERT_EQ(0, final);
+}
+
+TEST_F(device, MSI_TEST)
+{
+	int ret = -EINVAL;
+	int final = 0;
+
+	ret = ioctl(self->fd, PCITEST_SET_IRQTYPE, 1);
+	ASSERT_EQ(1, ret);
+
+	for (int i = 1; i <= 32; i++) {
+		ret = ioctl(self->fd, PCITEST_MSI, i);
+		EXPECT_EQ(1, ret) {
+			TH_LOG("TEST FAILED FOR MSI%d\n", i);
+			final++;
+		}
+	}
+
+	ASSERT_EQ(0, final);
+}
+
+TEST_F(device, READ_TEST)
+{
+	int final = 0;
+	int ret = -EINVAL;
+	unsigned long SIZE[5] = {1, 1024, 1025, 1024000, 1024001};
+
+	ret = ioctl(self->fd, PCITEST_SET_IRQTYPE, 1);
+	ASSERT_EQ(1, ret);
+
+	struct xfer_param param;
+
+	param.flag = 0;
+	for (int i = 0; i < 5; i++) {
+		param.size = SIZE[i];
+		ret = ioctl(self->fd, PCITEST_READ, &param);
+		EXPECT_EQ(1, ret) {
+			TH_LOG("TEST FAILED FOR size =%ld.\n", SIZE[i]);
+			final++;
+		}
+	}
+
+	ASSERT_EQ(0, final);
+}
+
+TEST_F(device, WRITE_TEST)
+{
+	int final = 0;
+	int ret = -EINVAL;
+	unsigned long SIZE[5] = {1, 1024, 1025, 1024000, 1024001};
+
+	ret = ioctl(self->fd, PCITEST_SET_IRQTYPE, 1);
+	ASSERT_EQ(1, ret);
+
+	struct xfer_param param;
+
+	param.flag = 0;
+
+	for (int i = 0; i < 5; i++) {
+		param.size = SIZE[i];
+		ret = ioctl(self->fd, PCITEST_WRITE, &param);
+		EXPECT_EQ(1, ret) {
+			TH_LOG("TEST FAILED FOR size =%ld.\n", SIZE[i]);
+			final++;
+		}
+	}
+
+	ASSERT_EQ(0, final);
+}
+
+TEST_F(device, COPY_TEST)
+{
+	int final = 0;
+	int ret = -EINVAL;
+	unsigned long SIZE[5] = {1, 1024, 1025, 1024000, 1024001};
+
+	ret = ioctl(self->fd, PCITEST_SET_IRQTYPE, 1);
+	ASSERT_EQ(1, ret);
+
+	struct xfer_param param;
+
+	param.flag = 0;
+
+	for (int i = 0; i < 5; i++) {
+		param.size = SIZE[i];
+		ret = ioctl(self->fd, PCITEST_COPY, &param);
+		EXPECT_EQ(1, ret) {
+			TH_LOG("TEST FAILED FOR size =%ld.\n", SIZE[i]);
+			final++;
+		}
+	}
+
+	ASSERT_EQ(0, final);
+}
+TEST_HARNESS_MAIN
