diff --git a/proto/context.proto b/proto/context.proto
index f5dec30796a8426f512947d369b8db5f5889471a..7763b8032a67327dd871c59bdb85bd22390e2a28 100644
--- a/proto/context.proto
+++ b/proto/context.proto
@@ -239,6 +239,7 @@ enum ServiceTypeEnum {
   SERVICETYPE_L3NM = 1;
   SERVICETYPE_L2NM = 2;
   SERVICETYPE_TAPI_CONNECTIVITY_SERVICE = 3;
+  SERVICETYPE_P4 = 4;
 }
 
 enum ServiceStatusEnum {
diff --git a/src/service/service/database/ServiceModel.py b/src/service/service/database/ServiceModel.py
index cf756af60a8178a9ae2fda2a5fa5ddeebc73912c..7a4492dcf087cca7a6ecb56708b558ccc7c6d9c3 100644
--- a/src/service/service/database/ServiceModel.py
+++ b/src/service/service/database/ServiceModel.py
@@ -34,6 +34,7 @@ class ORM_ServiceTypeEnum(Enum):
     L3NM                      = ServiceTypeEnum.SERVICETYPE_L3NM
     L2NM                      = ServiceTypeEnum.SERVICETYPE_L2NM
     TAPI_CONNECTIVITY_SERVICE = ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE
+    P4_SERVICE                = ServiceTypeEnum.SERVICETYPE_P4
 
 grpc_to_enum__service_type = functools.partial(
     grpc_to_enum, ServiceTypeEnum, ORM_ServiceTypeEnum)
diff --git a/src/service/service/service_handlers/__init__.py b/src/service/service/service_handlers/__init__.py
index 89e717722d152ce978dca10a768119d9e9adaf1e..a0f8ab13c992207c79b8b52f3be666bd426874de 100644
--- a/src/service/service/service_handlers/__init__.py
+++ b/src/service/service/service_handlers/__init__.py
@@ -17,6 +17,7 @@ from ..service_handler_api.FilterFields import FilterFieldEnum
 from .l2nm_emulated.L2NMEmulatedServiceHandler import L2NMEmulatedServiceHandler
 from .l3nm_emulated.L3NMEmulatedServiceHandler import L3NMEmulatedServiceHandler
 from .l3nm_openconfig.L3NMOpenConfigServiceHandler import L3NMOpenConfigServiceHandler
+from .p4.p4_service_handler import P4ServiceHandler
 from .tapi_tapi.TapiServiceHandler import TapiServiceHandler
 
 SERVICE_HANDLERS = [
@@ -44,4 +45,10 @@ SERVICE_HANDLERS = [
             FilterFieldEnum.DEVICE_DRIVER : DeviceDriverEnum.DEVICEDRIVER_TRANSPORT_API,
         }
     ]),
+    (P4ServiceHandler, [
+        {
+            FilterFieldEnum.SERVICE_TYPE: ORM_ServiceTypeEnum.P4_SERVICE,
+            FilterFieldEnum.DEVICE_DRIVER: ORM_DeviceDriverEnum.P4,
+        }
+    ]),
 ]
diff --git a/src/service/service/service_handlers/p4/__init__.py b/src/service/service/service_handlers/p4/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..9953c820575d42fa88351cc8de022d880ba96e6a
--- /dev/null
+++ b/src/service/service/service_handlers/p4/__init__.py
@@ -0,0 +1,13 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
diff --git a/src/service/service/service_handlers/p4/p4_service_handler.py b/src/service/service/service_handlers/p4/p4_service_handler.py
new file mode 100644
index 0000000000000000000000000000000000000000..690c6adbcf359f7ebb5df8b372f162fb48f81e12
--- /dev/null
+++ b/src/service/service/service_handlers/p4/p4_service_handler.py
@@ -0,0 +1,224 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+P4 service handler for the TeraFlow SDN controller.
+"""
+
+import json
+import logging
+from typing import Any, List, Optional, Tuple, Union
+from common.orm.Database import Database
+from common.orm.HighLevel import get_object
+from common.orm.backend.Tools import key_to_str
+# from common.proto.context_pb2 import Device
+# from common.tools.object_factory.ConfigRule import json_config_rule_delete,\
+#     json_config_rule_set
+from common.type_checkers.Checkers import chk_type
+from context.client.ContextClient import ContextClient
+from device.client.DeviceClient import DeviceClient
+from service.service.database.ConfigModel import get_config_rules
+from service.service.database.ContextModel import ContextModel
+# from service.service.database.DeviceModel import DeviceModel
+from service.service.database.ServiceModel import ServiceModel
+from service.service.service_handler_api._ServiceHandler import _ServiceHandler
+
+LOGGER = logging.getLogger(__name__)
+
+
+class P4ServiceHandler(_ServiceHandler):
+    """
+    P4ServiceHandler class inherits the abstract _ServiceHandler class
+    to provision network connectivity upon P4 devices.
+
+    Attributes
+    ----------
+    db_service: ServiceModel
+        The service instance from the local in-memory database.
+    database: Database
+        The instance of the local in-memory database.
+    context_client: ContextClient
+        gRPC client to get Context services
+    device_client : DeviceClient
+        gRPC client to get Device services
+    settings: map
+        Extra settings required by the service handler.
+    """
+    def __init__(self,  # pylint: disable=super-init-not-called
+                 db_service: ServiceModel,
+                 database: Database,
+                 context_client: ContextClient,
+                 device_client : DeviceClient,
+                 **settings) -> None:
+        self.__db_service = db_service
+        self.__database = database
+        self.__context_client = context_client
+        self.__device_client = device_client
+
+        self.__db_context: ContextModel = get_object(
+            self.__database, ContextModel, self.__db_service.context_fk)
+        str_service_key = key_to_str(
+            [self.__db_context.context_uuid, self.__db_service.service_uuid])
+        db_config = get_config_rules(
+            self.__database, str_service_key, "running")
+        self.__resolver = None
+        self.__config = None
+
+    def SetEndpoint(self, endpoints: List[Tuple[str, str, Optional[str]]]) \
+            -> List[Union[bool, Exception]]:
+        """
+        Create/Update service endpoints.
+
+        :param endpoints: list of tuples, each containing a device_uuid,
+        endpoint_uuid and, optionally, the topology_uuid of the endpoint to add.
+        :return: list of results for endpoint changes requested.
+        Return values must be in the same order as the requested endpoints.
+        If an endpoint is properly added, True must be returned;
+        otherwise, the Exception that is raised during processing
+        must be returned.
+        """
+        chk_type("endpoints", endpoints, list)
+        if len(endpoints) == 0:
+            return []
+        return []
+
+    def DeleteEndpoint(self, endpoints: List[Tuple[str, str, Optional[str]]]) \
+            -> List[Union[bool, Exception]]:
+        """
+        Delete service endpoints.
+
+        :param endpoints: list of tuples, each containing a device_uuid,
+        endpoint_uuid and, optionally, the topology_uuid of the endpoint to
+        delete.
+        :return: list of results for endpoint deletions requested.
+        Return values must be in the same order as the requested endpoints.
+        If an endpoint is properly deleted, True must be returned;
+        otherwise, the Exception that is raised during processing
+        must be returned.
+        """
+        chk_type("endpoints", endpoints, list)
+        if len(endpoints) == 0:
+            return []
+        return []
+
+    def SetConstraint(self, constraints: List[Tuple[str, Any]]) \
+            -> List[Union[bool, Exception]]:
+        """
+        Create/Update service constraints.
+
+        :param constraints: List of tuples, each containing a constraint_type
+        and the new constraint_value to be set.
+        :return: List of results for constraint changes requested.
+        Return values must be in the same order as the requested constraints.
+        If a constraint is properly set, True must be returned;
+        otherwise, the Exception that is raised during the processing
+        must be returned.
+        """
+        chk_type("constraints", constraints, list)
+        if len(constraints) == 0:
+            return []
+
+        msg = f"SetConstraint() not yet implemented by the" \
+              f" P4 service handler. \nThe following constraints " \
+              f"are being ignored: {str(constraints)}"
+        LOGGER.warning(msg)
+        return [Exception(msg) for _ in range(len(constraints))]
+
+    def DeleteConstraint(self, constraints: List[Tuple[str, Any]]) \
+            -> List[Union[bool, Exception]]:
+        """
+        Delete service constraints.
+
+        :param constraints: List of tuples, each containing a constraint_type
+        pointing to the constraint to be deleted, and a constraint_value
+        containing possible additionally required values to locate the
+        constraint to be removed.
+        :return: List of results for constraint deletions requested.
+        Return values must be in the same order as the requested constraints.
+        If a constraint is properly deleted, True must be returned;
+        otherwise, the Exception that is raised during the processing
+        must be returned.
+        """
+        chk_type("constraints", constraints, list)
+        if len(constraints) == 0:
+            return []
+
+        msg = f"DeleteConstraint() not yet implemented by the" \
+              f" P4 service handler. \nThe following constraints " \
+              f"are being ignored: {str(constraints)}"
+        LOGGER.warning(msg)
+        return [Exception(msg) for _ in range(len(constraints))]
+
+    def SetConfig(self, resources: List[Tuple[str, Any]]) \
+            -> List[Union[bool, Exception]]:
+        """
+        Create/Update configuration for a list of service resources.
+
+        :param resources: List of tuples, each containing a resource_key
+        pointing to the resource to be modified, and a resource_value
+        containing the new value to be set.
+        :return: List of results for resource key changes requested.
+        Return values must be in the same order as the requested resource keys.
+        If a resource is properly set, True must be returned;
+        otherwise, the Exception that is raised during the processing
+        must be returned.
+        """
+        chk_type("resources", resources, list)
+        if len(resources) == 0:
+            return []
+
+        results = []
+        for resource in resources:
+            try:
+                resource_key, resource_value = resource
+                resource_value = json.loads(resource_value)
+                # Do the job
+                # results.append(True)
+            except Exception as ex:  # pylint: disable=broad-except
+                LOGGER.exception(
+                    "Failed to execute SetConfig(%s)", str(resource))
+                results.append(ex)
+
+        return results
+
+    def DeleteConfig(self, resources: List[Tuple[str, Any]]) \
+            -> List[Union[bool, Exception]]:
+        """
+        Delete configuration for a list of service resources.
+
+        :param resources: List of tuples, each containing a resource_key
+        pointing to the resource to be modified, and a resource_value containing
+        possible additionally required values to locate the value to be removed.
+        :return: List of results for resource key deletions requested.
+        Return values must be in the same order as the requested resource keys.
+        If a resource is properly deleted, True must be returned;
+        otherwise, the Exception that is raised during the processing
+        must be returned.
+        """
+        chk_type("resources", resources, list)
+        if len(resources) == 0:
+            return []
+
+        results = []
+        for resource in resources:
+            try:
+                resource_key, _ = resource
+                # Do the job
+                # results.append(True)
+            except Exception as ex:  # pylint: disable=broad-except
+                LOGGER.exception(
+                    "Failed to execute DeleteConfig(%s)", str(resource))
+                results.append(ex)
+
+        return results
diff --git a/src/service/tests/test_unitary.py b/src/service/tests/test_unitary.py
index e12ec2bc4dda856d76acd50c90af4b7d7941fb00..bc25dbfbb634a852efab062b9294a022a73d7a35 100644
--- a/src/service/tests/test_unitary.py
+++ b/src/service/tests/test_unitary.py
@@ -15,12 +15,11 @@
 import copy, grpc, logging, pytest
 from common.proto.context_pb2 import (
     Context, ContextId, Device, DeviceId, Link, LinkId, Service, ServiceId, Topology, TopologyId)
-from common.tests.PytestGenerateTests import pytest_generate_tests # (required) pylint: disable=unused-import
 from common.tools.grpc.Tools import grpc_message_to_json_string
 from context.client.ContextClient import ContextClient
 from device.client.DeviceClient import DeviceClient
 from service.client.ServiceClient import ServiceClient
-from .PrepareTestScenario import ( # pylint: disable=unused-import
+from .PrepareTestScenario import (  # pylint: disable=unused-import
     # be careful, order of symbols is important here!
     mock_service, service_service, context_client, device_client, service_client)