diff --git a/MAINTAINERS b/MAINTAINERS
index 00f5a5f9e6..7998be98f1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1811,6 +1811,13 @@ F: dts/
 F: devtools/dts-check-format.sh
 F: doc/guides/tools/dts.rst
 
+Graph application
+M: Sunil Kumar Kori <skori@marvell.com>
+M: Rakesh Kudurumalla <rkudurumalla@marvell.com>
+F: app/graph/
+F: doc/guides/tools/graph.rst
+F: doc/guides/tools/img/graph-usecase-l3fwd.svg
+
 
 Other Example Applications
 --------------------------
diff --git a/app/graph/cli.c b/app/graph/cli.c
new file mode 100644
index 0000000000..473fa1635a
--- /dev/null
+++ b/app/graph/cli.c
@@ -0,0 +1,113 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2023 Marvell.
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <cmdline_parse.h>
+#include <cmdline_parse_num.h>
+#include <cmdline_parse_string.h>
+#include <cmdline_socket.h>
+#include <rte_common.h>
+
+#include "module_api.h"
+
+#define CMD_MAX_TOKENS 256
+#define MAX_LINE_SIZE 2048
+
+cmdline_parse_ctx_t modules_ctx[] = {
+	NULL,
+};
+
+static struct cmdline *cl;
+
+static int
+is_comment(char *in)
+{
+	if ((strlen(in) && index("!#%;", in[0])) ||
+		(strncmp(in, "//", 2) == 0) ||
+		(strncmp(in, "--", 2) == 0))
+		return 1;
+
+	return 0;
+}
+
+void
+cli_init(void)
+{
+	cl = cmdline_stdin_new(modules_ctx, "");
+}
+
+void
+cli_exit(void)
+{
+	cmdline_stdin_exit(cl);
+}
+
+void
+cli_process(char *in, char *out, size_t out_size, __rte_unused void *obj)
+{
+	int rc;
+
+	if (is_comment(in))
+		return;
+
+	rc = cmdline_parse(cl, in);
+	if (rc == CMDLINE_PARSE_AMBIGUOUS)
+		snprintf(out, out_size, MSG_CMD_FAIL, "Ambiguous command");
+	else if (rc == CMDLINE_PARSE_NOMATCH)
+		snprintf(out, out_size, MSG_CMD_FAIL, "Command mismatch");
+	else if (rc == CMDLINE_PARSE_BAD_ARGS)
+		snprintf(out, out_size, MSG_CMD_FAIL, "Bad arguments");
+
+	return;
+
+}
+
+int
+cli_script_process(const char *file_name, size_t msg_in_len_max, size_t msg_out_len_max, void *obj)
+{
+	char *msg_in = NULL, *msg_out = NULL;
+	FILE *f = NULL;
+
+	/* Check input arguments */
+	if ((file_name == NULL) || (strlen(file_name) == 0) || (msg_in_len_max == 0) ||
+	    (msg_out_len_max == 0))
+		return -EINVAL;
+
+	msg_in = malloc(msg_in_len_max + 1);
+	msg_out = malloc(msg_out_len_max + 1);
+	if ((msg_in == NULL) || (msg_out == NULL)) {
+		free(msg_out);
+		free(msg_in);
+		return -ENOMEM;
+	}
+
+	/* Open input file */
+	f = fopen(file_name, "r");
+	if (f == NULL) {
+		free(msg_out);
+		free(msg_in);
+		return -EIO;
+	}
+
+	/* Read file */
+	while (fgets(msg_in, msg_in_len_max, f) != NULL) {
+		msg_out[0] = 0;
+
+		cli_process(msg_in, msg_out, msg_out_len_max, obj);
+
+		if (strlen(msg_out))
+			printf("%s", msg_out);
+	}
+
+	/* Close file */
+	fclose(f);
+	free(msg_out);
+	free(msg_in);
+	return 0;
+}
diff --git a/app/graph/cli.h b/app/graph/cli.h
new file mode 100644
index 0000000000..652f948352
--- /dev/null
+++ b/app/graph/cli.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2023 Marvell.
+ */
+
+#ifndef APP_GRAPH_CLI_H
+#define APP_GRAPH_CLI_H
+
+/* Macros */
+#define MSG_OUT_OF_MEMORY   "Not enough memory.\n"
+#define MSG_CMD_UNKNOWN     "Unknown command \"%s\".\n"
+#define MSG_CMD_UNIMPLEM    "Command \"%s\" not implemented.\n"
+#define MSG_ARG_NOT_ENOUGH  "Not enough arguments for command \"%s\".\n"
+#define MSG_ARG_TOO_MANY    "Too many arguments for command \"%s\".\n"
+#define MSG_ARG_MISMATCH    "Wrong number of arguments for command \"%s\".\n"
+#define MSG_ARG_NOT_FOUND   "Argument \"%s\" not found.\n"
+#define MSG_ARG_INVALID     "Invalid value for argument \"%s\".\n"
+#define MSG_FILE_ERR        "Error in file \"%s\" at line %u.\n"
+#define MSG_FILE_NOT_ENOUGH "Not enough rules in file \"%s\".\n"
+#define MSG_CMD_FAIL        "Command \"%s\" failed.\n"
+
+#define APP_CLI_CMD_NAME_SIZE	64
+
+void cli_init(void);
+
+void cli_exit(void);
+
+void cli_process(char *in, char *out, size_t out_size, void *arg);
+
+int cli_script_process(const char *file_name, size_t msg_in_len_max, size_t msg_out_len_max,
+		       void *arg);
+
+#endif
diff --git a/app/graph/main.c b/app/graph/main.c
new file mode 100644
index 0000000000..734a94444e
--- /dev/null
+++ b/app/graph/main.c
@@ -0,0 +1,128 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2023 Marvell.
+ */
+
+#include <fcntl.h>
+#include <getopt.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/select.h>
+#include <unistd.h>
+
+#include <rte_eal.h>
+#include <rte_launch.h>
+
+#include "module_api.h"
+
+volatile bool force_quit;
+
+static const char usage[] = "%s EAL_ARGS -- -s SCRIPT "
+			    "[--help]\n";
+
+static struct app_params {
+	char *script_name;
+} app = {
+	.script_name = NULL,
+};
+
+static void
+signal_handler(int signum)
+{
+	if (signum == SIGINT || signum == SIGTERM) {
+		printf("\n\nSignal %d received, preparing to exit...\n", signum);
+		force_quit = true;
+	}
+}
+
+static int
+app_args_parse(int argc, char **argv)
+{
+	struct option lgopts[] = {
+		{"help", 0, 0, 'H'},
+	};
+	int s_present, n_args, i;
+	char *app_name = argv[0];
+	int opt, option_index;
+
+	/* Skip EAL input args */
+	n_args = argc;
+	for (i = 0; i < n_args; i++)
+		if (strcmp(argv[i], "--") == 0) {
+			argc -= i;
+			argv += i;
+			break;
+		}
+
+	if (i == n_args)
+		return 0;
+
+	/* Parse args */
+	s_present = 0;
+
+	while ((opt = getopt_long(argc, argv, "s:", lgopts, &option_index)) != EOF) {
+		switch (opt) {
+		case 's':
+			if (s_present) {
+				printf("Error: Multiple -s arguments\n");
+				return -1;
+			}
+			s_present = 1;
+
+			if (!strlen(optarg)) {
+				printf("Error: Argument for -s not provided\n");
+				return -1;
+			}
+
+			app.script_name = strdup(optarg);
+			if (app.script_name == NULL) {
+				printf("Error: Not enough memory\n");
+				return -1;
+			}
+			break;
+
+		case 'H':
+		default:
+			printf(usage, app_name);
+			return -1;
+		}
+	}
+	optind = 1; /* reset getopt lib */
+
+	return 0;
+}
+
+int
+main(int argc, char **argv)
+{
+	int rc;
+
+	/* Parse application arguments */
+	rc = app_args_parse(argc, argv);
+	if (rc < 0)
+		return rc;
+
+	/* EAL */
+	rc = rte_eal_init(argc, argv);
+	if (rc < 0) {
+		printf("Error: EAL initialization failed (%d)\n", rc);
+		return rc;
+	};
+
+	force_quit = false;
+	signal(SIGINT, signal_handler);
+	signal(SIGTERM, signal_handler);
+
+	cli_init();
+
+	/* Script */
+	if (app.script_name) {
+		cli_script_process(app.script_name, 0,
+			0, NULL);
+	}
+
+	cli_exit();
+	rte_eal_cleanup();
+	return 0;
+}
diff --git a/app/graph/meson.build b/app/graph/meson.build
new file mode 100644
index 0000000000..87c4ce30a8
--- /dev/null
+++ b/app/graph/meson.build
@@ -0,0 +1,14 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2023 Marvell.
+
+# override default name to drop the hyphen
+name = 'graph'
+if not build
+    subdir_done()
+endif
+
+deps += ['bus_pci', 'graph', 'eal', 'lpm', 'ethdev', 'node', 'cmdline']
+sources = files(
+        'cli.c',
+        'main.c',
+)
diff --git a/app/graph/module_api.h b/app/graph/module_api.h
new file mode 100644
index 0000000000..372aeae7e3
--- /dev/null
+++ b/app/graph/module_api.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2023 Marvell.
+ */
+
+#ifndef APP_GRAPH_MODULE_API_H
+#define APP_GRAPH_MODULE_API_H
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "cli.h"
+/*
+ * Externs
+ */
+extern volatile bool force_quit;
+
+#endif
diff --git a/app/meson.build b/app/meson.build
index e4bf5c531c..728c936383 100644
--- a/app/meson.build
+++ b/app/meson.build
@@ -17,6 +17,7 @@ endif
 apps = [
         'dumpcap',
         'pdump',
+        'graph',
         'proc-info',
         'test-acl',
         'test-bbdev',
diff --git a/doc/guides/tools/graph.rst b/doc/guides/tools/graph.rst
new file mode 100644
index 0000000000..271a85896d
--- /dev/null
+++ b/doc/guides/tools/graph.rst
@@ -0,0 +1,82 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright(c) 2023 Marvell.
+
+dpdk-graph Application
+======================
+
+The ``dpdk-graph`` tool is a Data Plane Development Kit (DPDK)
+application that allows exercising various graph use cases.
+This application has a generic framework to add new graph based use cases to
+verify functionality. Each use case is defined as a ``<usecase>.cli`` file.
+Based on the input file, application creates a graph to cater the use case.
+
+Supported Use cases
+-------------------
+ *
+
+Running the Application
+-----------------------
+
+The application has a number of command line options which can be provided in
+following syntax
+
+.. code-block:: console
+
+   dpdk-graph [EAL Options] -- [application options]
+
+EAL Options
+~~~~~~~~~~~
+
+Following are the EAL command-line options that can be used in conjunction
+with the ``dpdk-graph`` application.
+See the DPDK Getting Started Guides for more information on these options.
+
+*   ``-c <COREMASK>`` or ``-l <CORELIST>``
+
+        Set the hexadecimal bit mask of the cores to run on. The CORELIST is a
+        list of cores to be used.
+
+Application Options
+~~~~~~~~~~~~~~~~~~~
+
+Following are the application command-line options:
+
+* ``-s``
+
+        Script name with absolute path which specifies the use case. It is
+        a mandatory parameter which will be used to create desired graph
+        for a given use case.
+
+* ``--help``
+
+       Dumps application usage
+
+Supported CLI commands
+----------------------
+
+This section provides details on commands which can be used in ``<usecase>.cli``
+file to express the requested use case configuration.
+
+.. list-table:: Exposed CLIs
+   :widths: 40 40 10 10
+   :header-rows: 1
+   :class: longtable
+
+   * - Command
+     - Description
+     - Dynamic
+     - Optional
+   * - Dummy command
+     - Dummy command description
+     - No
+     - No
+
+Runtime configuration
+---------------------
+
+
+Created graph for use case
+--------------------------
+
+On the successful execution of ``<usecase>.cli`` file, corresponding graph will be created.
+This section mentions the created graph for each use case.
diff --git a/doc/guides/tools/index.rst b/doc/guides/tools/index.rst
index f2afb1fcc5..4f4dc8b518 100644
--- a/doc/guides/tools/index.rst
+++ b/doc/guides/tools/index.rst
@@ -23,4 +23,5 @@ DPDK Tools User Guides
     testeventdev
     testregex
     testmldev
+    graph
     dts
