diff --git a/core/Makefile.inc b/core/Makefile.inc
index f80019b6..263a0e50 100644
--- a/core/Makefile.inc
+++ b/core/Makefile.inc
@@ -22,8 +22,12 @@ endif
 
 CORE=core/built-in.a
 
+ifeq ($(CONFIG_PLDM),1)
+include $(SRC)/core/pldm/Makefile.inc
+endif
+
 CFLAGS_SKIP_core/relocate.o = -pg -fstack-protector-all
 CFLAGS_SKIP_core/relocate.o += -fstack-protector -fstack-protector-strong
 CFLAGS_SKIP_core/relocate.o += -fprofile-arcs -ftest-coverage
 
-$(CORE): $(CORE_OBJS:%=core/%)
+$(CORE): $(CORE_OBJS:%=core/%) $(PLDM)
diff --git a/core/pldm/Makefile.inc b/core/pldm/Makefile.inc
new file mode 100644
index 00000000..005c7b94
--- /dev/null
+++ b/core/pldm/Makefile.inc
@@ -0,0 +1,13 @@
+# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+# Copyright 2022 IBM Corp
+
+PLDM_DIR ?= core/pldm
+SUBDIRS += $(PLDM_DIR)
+
+CPPFLAGS += -I$(SRC)/pldm/libpldm/
+CPPFLAGS += -I$(SRC)/pldm/ibm/libpldm/
+
+PLDM_OBJS = pldm-common.o
+
+PLDM = $(PLDM_DIR)/built-in.a
+$(PLDM): $(PLDM_OBJS:%=$(PLDM_DIR)/%)
diff --git a/core/pldm/pldm-common.c b/core/pldm/pldm-common.c
new file mode 100644
index 00000000..b68e43d9
--- /dev/null
+++ b/core/pldm/pldm-common.c
@@ -0,0 +1,113 @@
+// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+// Copyright 2022 IBM Corp.
+
+#define pr_fmt(fmt) "PLDM: " fmt
+
+#include <cpu.h>
+#include <opal.h>
+#include <stdio.h>
+#include <string.h>
+#include <ast.h>
+#include "pldm.h"
+
+/*
+ * Print content of PLDM message in hex mode.
+ * 15 bytes per line.
+ * Ex: pldm_send: 000: 08 01 00 00 02 00 01
+ */
+void printbuf(const char *name, const char *msg, int len)
+{
+	int i, j;
+	char linebuf[128];
+
+	linebuf[0] = 0;
+
+	for (i = 0; i < len; i += j) {
+		linebuf[0] = 0;
+		for (j = 0; i + j < len && j < 15; j++) {
+			char s[5];
+
+			snprintf(s, 5, "%02x ", msg[i + j]);
+			strcat(linebuf, s);
+		}
+		prlog(PR_TRACE, "%s: %03x: %s\n", name, i, linebuf);
+	}
+}
+
+/*
+ * Send PLDM message over MCTP
+ */
+int pldm_send(uint8_t dest_id, uint8_t *buf, int len)
+{
+	uint8_t *msg;
+	int rc;
+
+	/* Message TYPE: PLDM = 0x01 (000_0001b) - DSP0240 */
+	msg = malloc(len + 1);
+	msg[0] = 0x01;
+	memcpy(&msg[1], buf, len);
+
+	rc = ast_mctp_message_tx(dest_id, msg, len + 1);
+	free(msg);
+
+	return rc;
+}
+
+/*
+ * Handle messages received from MCTP
+ */
+static int pldm_handle(uint8_t eid, const uint8_t *buf, int len)
+{
+	struct pldm_rx_data rx;
+
+	if (len < sizeof(rx.msg->hdr)) {
+		prlog(PR_ERR, "%s: packet is smaller than pldm header\n", __func__);
+		return OPAL_EMPTY;
+	}
+
+	memset(&rx, 0, sizeof(rx));
+	rx.msg = (struct pldm_msg *) buf;
+	rx.source_eid = eid;
+	rx.msg_len = len;
+
+	if (unpack_pldm_header(&rx.msg->hdr, &rx.hdrinf)) {
+		prlog(PR_ERR, "%s: unable to decode header\n", __func__);
+		return OPAL_EMPTY;
+	}
+
+	return OPAL_UNSUPPORTED;
+}
+
+/*
+ * MCTP message rx callback
+ */
+static void pldm_rx_message(uint8_t eid, bool tag_owner __unused,
+			    uint8_t msg_tag __unused, void *data __unused,
+			    void *vmsg, size_t len)
+{
+	uint8_t *msg = vmsg;
+
+	prlog(PR_TRACE, "message received: msg: %p, len %zd (eid: %d)\n",
+			 msg, len, eid);
+
+	/* pldm message type */
+	if ((msg[0] & 0x7f) != 0x01) {
+		prlog(PR_ERR, "%s, not a pldm message type\n", __func__);
+		return;
+	}
+
+	pldm_handle(eid, &msg[1], len - 1);
+}
+
+int pldm_mctp_init(void)
+{
+	int rc;
+
+	/* MCTP Binding */
+	rc = ast_mctp_init(pldm_rx_message);
+	if (rc)
+		prlog(PR_ERR, "Failed to bind MCTP\n");
+
+	prlog(PR_NOTICE, "%s - done (rc: %d)\n", __func__, rc);
+	return rc;
+}
diff --git a/core/pldm/pldm.h b/core/pldm/pldm.h
new file mode 100644
index 00000000..8dbd2260
--- /dev/null
+++ b/core/pldm/pldm.h
@@ -0,0 +1,40 @@
+/* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+ * Copyright 2022 IBM Corp.
+ */
+
+#ifndef __COREPLDM_H__
+#define __COREPLDM_H__
+
+#include <pldm/libpldm/base.h>
+#include <pldm.h>
+
+/* Common support */
+
+void printbuf(const char *name, const char *msg, int len);
+
+/*
+ * For the EIDs: the valid range is 8-254.
+ * BMC EID default = 8.
+ */
+# define BMC_EID  8
+
+struct pldm_rx_data {
+	struct pldm_header_info hdrinf; /* parsed message header */
+
+	struct pldm_msg *msg;
+	int msg_len;
+	int source_eid;
+};
+
+struct pldm_type {
+	const char *name;
+	int pldm_type_id;
+	ver32_t version;
+
+	struct list_head commands;
+	struct list_node link;
+};
+
+int pldm_send(uint8_t dest_id, uint8_t *buf, int len);
+
+#endif /* __COREPLDM_H__ */
diff --git a/include/pldm.h b/include/pldm.h
new file mode 100644
index 00000000..d542e0eb
--- /dev/null
+++ b/include/pldm.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+ * Copyright 2022 IBM Corp.
+ */
+
+#ifndef __PLDM_H__
+#define __PLDM_H__
+
+/**
+ * PLDM over MCTP initialization
+ */
+int pldm_mctp_init(void);
+
+#endif /* __PLDM_H__ */
