diff --git a/internal/clients/onos.go b/internal/clients/onos.go
new file mode 100644
index 0000000..2de584c
--- /dev/null
+++ b/internal/clients/onos.go
@@ -0,0 +1,254 @@
+/*
+* Copyright 2022-present Open Networking Foundation
+
+* 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.
+ */
+
+package clients
+
+import (
+	"context"
+	"encoding/json"
+	"fmt"
+	"io"
+	"net/http"
+	"time"
+
+	"github.com/opencord/voltha-lib-go/v7/pkg/log"
+)
+
+const (
+	onosHttpRequestTimeout = time.Second * 10
+	onosBackoffInterval    = time.Second * 10
+)
+
+type OnosClient struct {
+	httpClient *http.Client
+	endpoint   string
+	username   string
+	password   string
+}
+
+type RestResponse struct {
+	Body string
+	Code int
+}
+
+// Creates a new olt app client
+func NewOnosClient(endpoint string, user string, pass string) *OnosClient {
+	return &OnosClient{
+		httpClient: &http.Client{
+			Timeout: onosHttpRequestTimeout,
+		},
+		endpoint: endpoint,
+		username: user,
+		password: pass,
+	}
+}
+
+func (c *OnosClient) CheckConnection(ctx context.Context) error {
+	logger.Debugw(ctx, "checking-connection-to-onos-olt-app-api", log.Fields{"endpoint": c.endpoint})
+
+	for {
+		if resp, err := c.GetStatus(); err == nil {
+			logger.Debug(ctx, "onos-olt-app-api-reachable")
+			break
+		} else {
+			logger.Warnw(ctx, "onos-olt-app-api-not-ready", log.Fields{
+				"err":      err,
+				"response": resp,
+			})
+		}
+
+		//Wait a bit before trying again
+		select {
+		case <-ctx.Done():
+			return fmt.Errorf("onos-olt-app-connection-stopped-due-to-context-done")
+		case <-time.After(onosBackoffInterval):
+			continue
+		}
+	}
+
+	return nil
+}
+
+func (c *OnosClient) makeRequest(method string, url string) (RestResponse, error) {
+	result := RestResponse{Code: 0}
+
+	req, err := http.NewRequest(method, url, nil)
+	if err != nil {
+		return result, fmt.Errorf("cannot-create-request: %s", err)
+	}
+
+	req.SetBasicAuth(c.username, c.password)
+
+	resp, err := c.httpClient.Do(req)
+	if err != nil {
+		return result, fmt.Errorf("cannot-get-response: %s", err)
+	}
+	defer resp.Body.Close()
+
+	buffer, err := io.ReadAll(resp.Body)
+	if err != nil {
+		return result, fmt.Errorf("error-while-reading-response-body: %s", err)
+	}
+
+	result.Body = string(buffer)
+	result.Code = resp.StatusCode
+
+	if result.Code != http.StatusOK {
+		return result, fmt.Errorf("status-code-not-ok: %s %s %d", method, url, result.Code)
+	}
+
+	return result, nil
+}
+
+///////////////////////////////////////////////////////////////////////// ONOS OLT app APIs
+
+func (c *OnosClient) GetStatus() (RestResponse, error) {
+	method := http.MethodGet
+	url := fmt.Sprintf("http://%s/onos/olt/oltapp/status", c.endpoint)
+
+	return c.makeRequest(method, url)
+}
+
+func (c *OnosClient) ProvisionService(portName string, sTag string, cTag string, technologyProfileId string) (RestResponse, error) {
+	method := http.MethodPost
+	url := fmt.Sprintf("http://%s/onos/olt/oltapp/services/%s/%s/%s/%s", c.endpoint, portName, sTag, cTag, technologyProfileId)
+
+	return c.makeRequest(method, url)
+}
+
+func (c *OnosClient) RemoveService(portName string, sTag string, cTag string, trafficProfileId string) (RestResponse, error) {
+	method := http.MethodDelete
+	url := fmt.Sprintf("http://%s/onos/olt/oltapp/services/%s/%s/%s/%s", c.endpoint, portName, sTag, cTag, trafficProfileId)
+
+	return c.makeRequest(method, url)
+}
+
+type ProgrammedSubscriber struct {
+	Location string      `json:"location"`
+	TagInfo  SadisUniTag `json:"tagInfo"`
+}
+
+type SadisUniTag struct {
+	UniTagMatch                   int    `json:"uniTagMatch,omitempty"`
+	PonCTag                       int    `json:"ponCTag,omitempty"`
+	PonSTag                       int    `json:"ponSTag,omitempty"`
+	TechnologyProfileID           int    `json:"technologyProfileId,omitempty"`
+	UpstreamBandwidthProfile      string `json:"upstreamBandwidthProfile,omitempty"`
+	UpstreamOltBandwidthProfile   string `json:"upstreamOltBandwidthProfile,omitempty"`
+	DownstreamBandwidthProfile    string `json:"downstreamBandwidthProfile,omitempty"`
+	DownstreamOltBandwidthProfile string `json:"downstreamOltBandwidthProfile,omitempty"`
+	IsDhcpRequired                bool   `json:"isDhcpRequired,omitempty"`
+	IsIgmpRequired                bool   `json:"isIgmpRequired,omitempty"`
+	IsPPPoERequired               bool   `json:"isPppoeRequired,omitempty"`
+	ConfiguredMacAddress          string `json:"configuredMacAddress,omitempty"`
+	EnableMacLearning             bool   `json:"enableMacLearning,omitempty"`
+	UsPonCTagPriority             int    `json:"usPonCTagPriority,omitempty"`
+	UsPonSTagPriority             int    `json:"usPonSTagPriority,omitempty"`
+	DsPonCTagPriority             int    `json:"dsPonCTagPriority,omitempty"`
+	DsPonSTagPriority             int    `json:"dsPonSTagPriority,omitempty"`
+	ServiceName                   string `json:"serviceName,omitempty"`
+}
+
+func (c *OnosClient) GetProgrammedSubscribers() ([]ProgrammedSubscriber, error) {
+	method := http.MethodGet
+	url := fmt.Sprintf("http://%s/onos/olt/oltapp/programmed-subscribers", c.endpoint)
+
+	response, err := c.makeRequest(method, url)
+	if err != nil {
+		return nil, err
+	}
+
+	var subscribers struct {
+		Entries []ProgrammedSubscriber `json:"entries"`
+	}
+	err = json.Unmarshal([]byte(response.Body), &subscribers)
+	if err != nil {
+		return nil, err
+	}
+
+	return subscribers.Entries, nil
+}
+
+///////////////////////////////////////////////////////////////////////// ONOS Core APIs
+
+type OnosPort struct {
+	Element     string            `json:"element"` //Device ID
+	Port        string            `json:"port"`    //Port number
+	IsEnabled   bool              `json:"isEnabled"`
+	Type        string            `json:"type"`
+	PortSpeed   uint              `json:"portSpeed"`
+	Annotations map[string]string `json:"annotations"`
+}
+
+func (c *OnosClient) GetPorts() ([]OnosPort, error) {
+	method := http.MethodGet
+	url := fmt.Sprintf("http://%s/onos/v1/devices/ports", c.endpoint)
+
+	response, err := c.makeRequest(method, url)
+	if err != nil {
+		return nil, err
+	}
+
+	var ports struct {
+		Ports []OnosPort `json:"ports"`
+	}
+	err = json.Unmarshal([]byte(response.Body), &ports)
+	if err != nil {
+		return nil, err
+	}
+
+	return ports.Ports, nil
+}
+
+///////////////////////////////////////////////////////////////////////// ONOS SADIS APIs
+
+type BandwidthProfile struct {
+	Id  string `json:"id"`
+	Cir int64  `json:"cir"`
+	Cbs string `json:"cbs"`
+	Air int64  `json:"air"`
+	Gir int64  `json:"gir"`
+	Eir int64  `json:"eir"`
+	Ebs string `json:"ebs"`
+	Pir int64  `json:"pir"`
+	Pbs string `json:"pbs"`
+}
+
+func (c *OnosClient) GetBandwidthProfile(id string) (*BandwidthProfile, error) {
+	method := http.MethodGet
+	url := fmt.Sprintf("http://%s/onos/sadis/bandwidthprofile/%s", c.endpoint, id)
+
+	response, err := c.makeRequest(method, url)
+	if err != nil {
+		return nil, err
+	}
+
+	var bwProfiles struct {
+		Entry []BandwidthProfile `json:"entry"`
+	}
+	err = json.Unmarshal([]byte(response.Body), &bwProfiles)
+	if err != nil {
+		return nil, err
+	}
+
+	//The response has a list, but always returns one item
+	//Verify this is correct and return it
+	if len(bwProfiles.Entry) != 1 {
+		return nil, fmt.Errorf("unexpected-number-of-bw-profile-entries: id=%s len=%d", id, len(bwProfiles.Entry))
+	}
+
+	return &bwProfiles.Entry[0], nil
+}
