diff --git a/debian/sonic-mgmt-common.install b/debian/sonic-mgmt-common.install
index b9bdf7ff3815..4d28ffda7bf3 100644
--- a/debian/sonic-mgmt-common.install
+++ b/debian/sonic-mgmt-common.install
@@ -6,6 +6,7 @@ models/yang/sonic/*.yang            usr/models/yang
 models/yang/sonic/common/*.yang     usr/models/yang
 models/yang/annotations/*.yang      usr/models/yang
 config/transformer/models_list      usr/models/yang
+models/yang/version.xml             usr/models/yang
 
 # CVL files
 build/cvl/schema        usr/sbin
diff --git a/models/yang/README.md b/models/yang/README.md
new file mode 100644
index 000000000000..1bcc3a1d0549
--- /dev/null
+++ b/models/yang/README.md
@@ -0,0 +1,51 @@
+# YANG directory
+
+## Directory structure
+
+    yang/               --> Standard YANGs
+    |-- annotations/    --> Transformer annotations
+    |-- common/         --> Dependencies for standard YANGs
+    |-- extensions/     --> Extenstions for standard YANGs
+    |-- sonic/          --> SONiC yangs
+    |-- testdata/       --> Test YANGs - ignored
+    `-- version.xml     --> YANG bundle version configuration file
+
+All supported standard YANG files (OpenConfig and IETF) are kept in this **yang** directory. Usual practice is to keep only top level YANG module here and keep dependent YANGs, submodules in **yang/common** directory.
+
+Example: openconfig-platform.yang is kept in top **yang** directory and openconfig-platform-types.yang in **yang/common** directory.
+
+All extenstion YANGs **MUST** be kept in **yang/extensions** directory.
+
+## version.xml
+
+version.xml file maintains the yang bundle version number in **Major.Minor.Patch** format.
+It is the collective version number for all the YANG modules defined here.
+**UPDATE THIS VERSION NUMBER FOR EVERY YANG CHANGE.**
+
+**Major version** should be incremented if YANG model is changed in a non backward compatible manner.
+Such changes should be avoided.
+
+* Delete, rename or relocate data node
+* Change list key attributes
+* Change data type of a node to an incompatible type
+* Change leafref target
+
+**Minor version** should be incremented if the YANG change modifies the API in a backward
+compatible way. Patch version should be reset to 0.
+Candidate YANG changes for this category are:
+
+* Add new YANG module
+* Add new YANG data nodes
+* Mark a YANG data node as deprecated
+* Change data type of a node to a compatible type
+* Add new enum or identity
+
+**Patch version** should incremented for cosmetic fixes that do not change YANG API.
+Candidate YANG changes for this category are:
+
+* Change description, beautification.
+* Expand pattern or range of a node to wider set.
+* Change must expression to accept more cases.
+* Error message or error tag changes.
+
+
diff --git a/models/yang/version.xml b/models/yang/version.xml
new file mode 100644
index 000000000000..3028d6b5875b
--- /dev/null
+++ b/models/yang/version.xml
@@ -0,0 +1,36 @@
+<version-config>
+  <!--
+  yang-bundle-version configuration indicates the version
+  for the collection of all yang modules.
+
+  Update the version numbers here for every yang change.
+
+  Bump up MAJOR version only if the yang change are not
+  backward compatible.
+    + Renaming or relocating of data nodes
+    + Deleting unsupported configs
+    + Changing list key attributes
+    + Incompatible data type changes
+    + Changing leafref target
+
+  Bump up MINOR version number for all backward compatible
+  API changes.
+    + Add new config node
+    + Data type changes like pattern, range (that are backward compatibile)
+    + Adding new enum/identity
+
+  Bump up PATCH number for cosmetic fixes that do not affect any API
+    + Description changes, beautification
+    + Must expression and validations that are backward compatibile
+    + error-tag, error-message
+    + max-elements, min-elements
+    + Mark a node as deprecated
+  -->
+  <yang-bundle-version>
+    <Major>1</Major>
+    <Minor>0</Minor>
+    <Patch>0</Patch>
+  </yang-bundle-version>
+
+</version-config>
+
diff --git a/translib/app_interface.go b/translib/app_interface.go
index bb56988a0fdc..7929a11eab0a 100644
--- a/translib/app_interface.go
+++ b/translib/app_interface.go
@@ -63,6 +63,10 @@ type appOptions struct {
     // 0 indicates unlimited depth.
     // Valid for GET API only.
     depth uint
+
+    // deleteEmptyEntry indicates if the db entry should be deleted upon
+    // deletion of last field. This is a non standard option.
+    deleteEmptyEntry bool
 }
 
 //map containing the base path to app module info
diff --git a/translib/authorize.go b/translib/authorize.go
new file mode 100644
index 000000000000..c84b4b9bef0c
--- /dev/null
+++ b/translib/authorize.go
@@ -0,0 +1,81 @@
+////////////////////////////////////////////////////////////////////////////////
+//                                                                            //
+//  Copyright 2019 Broadcom. The term Broadcom refers to Broadcom Inc. and/or //
+//  its subsidiaries.                                                         //
+//                                                                            //
+//  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 translib defines the functions to be used to authorize
+
+an incoming user. It also includes caching of the UserDB data
+
+needed to authorize the user.
+
+*/
+
+package translib
+
+func isAuthorizedForSet(req SetRequest) bool {
+	if !req.AuthEnabled {
+		return true
+	}
+	for _, r := range req.User.Roles {
+		if r == "admin" {
+			return true
+		}
+	}
+	return false
+}
+
+func isAuthorizedForBulk(req BulkRequest) bool {
+	if !req.AuthEnabled {
+		return true
+	}
+	for _, r := range req.User.Roles {
+		if r == "admin" {
+			return true
+		}
+	}
+	return false
+}
+
+func isAuthorizedForGet(req GetRequest) bool {
+	if !req.AuthEnabled {
+		return true
+	}
+	return true
+}
+
+func isAuthorizedForSubscribe(req SubscribeRequest) bool {
+	if !req.AuthEnabled {
+		return true
+	}
+	return true
+}
+
+func isAuthorizedForIsSubscribe(req IsSubscribeRequest) bool {
+	if !req.AuthEnabled {
+		return true
+	}
+	return true
+}
+
+func isAuthorizedForAction(req ActionRequest) bool {
+	if !req.AuthEnabled {
+		return true
+	}
+	return true
+}
diff --git a/translib/tlerr/app_errors.go b/translib/tlerr/app_errors.go
index d6959543269c..289cb84b37b6 100644
--- a/translib/tlerr/app_errors.go
+++ b/translib/tlerr/app_errors.go
@@ -45,6 +45,9 @@ type NotSupportedError errordata
 // InternalError indicates a generic error during app execution.
 type InternalError errordata
 
+// AuthorizationError indicates the user is not authorized for an operation.
+type AuthorizationError errordata
+
 /////////////
 
 func (e InvalidArgsError) Error() string {
@@ -90,3 +93,8 @@ func (e InternalError) Error() string {
 func New(msg string, args ...interface{}) InternalError {
 	return InternalError{Format: msg, Args: args}
 }
+
+func (e AuthorizationError) Error() string {
+    return p.Sprintf(e.Format, e.Args...)
+}
+
diff --git a/translib/tlerr/tlerr.go b/translib/tlerr/tlerr.go
index a920e67f43f6..350a8602166b 100644
--- a/translib/tlerr/tlerr.go
+++ b/translib/tlerr/tlerr.go
@@ -101,3 +101,14 @@ type TranslibSyntaxValidationError struct {
 func (e TranslibSyntaxValidationError) Error() string {
 	return p.Sprintf("%s", e.ErrorStr)
 }
+
+type TranslibUnsupportedClientVersion struct {
+    ClientVersion string
+    ServerVersion string
+    ServerBaseVersion string
+}
+
+func (e TranslibUnsupportedClientVersion) Error() string {
+    return p.Sprintf("Unsupported client version %s", e.ClientVersion)
+}
+
diff --git a/translib/translib.go b/translib/translib.go
index c222503ceb77..737d530fa086 100644
--- a/translib/translib.go
+++ b/translib/translib.go
@@ -47,7 +47,7 @@ var writeMutex = &sync.Mutex{}
 //Interval value for interval based subscription needs to be within the min and max
 //minimum global interval for interval based subscribe in secs
 var minSubsInterval = 20
-//minimum global interval for interval based subscribe in secs
+//maximum global interval for interval based subscribe in secs
 var maxSubsInterval = 600
 
 type ErrSource int
@@ -68,6 +68,7 @@ type SetRequest struct {
 	User    UserRoles
 	AuthEnabled bool
 	ClientVersion Version
+	DeleteEmptyEntry bool
 }
 
 type SetResponse struct {
@@ -183,6 +184,12 @@ func Create(req SetRequest) (SetResponse, error) {
 	var resp SetResponse
 	path := req.Path
 	payload := req.Payload
+	if !isAuthorizedForSet(req) {
+		return resp, tlerr.AuthorizationError{
+			Format: "User is unauthorized for Create Operation",
+			Path: path,
+		}
+	}
 
 	log.Info("Create request received with path =", path)
 	log.Info("Create request received with payload =", string(payload))
@@ -251,6 +258,13 @@ func Update(req SetRequest) (SetResponse, error) {
 	var resp SetResponse
 	path := req.Path
 	payload := req.Payload
+	if !isAuthorizedForSet(req) {
+		return resp, tlerr.AuthorizationError{
+			Format: "User is unauthorized for Update Operation",
+			Path: path,
+		}
+	}
+
 
 	log.Info("Update request received with path =", path)
 	log.Info("Update request received with payload =", string(payload))
@@ -320,6 +334,12 @@ func Replace(req SetRequest) (SetResponse, error) {
 	var resp SetResponse
 	path := req.Path
 	payload := req.Payload
+	if !isAuthorizedForSet(req) {
+		return resp, tlerr.AuthorizationError{
+			Format: "User is unauthorized for Replace Operation",
+			Path: path,
+		}
+	}
 
 	log.Info("Replace request received with path =", path)
 	log.Info("Replace request received with payload =", string(payload))
@@ -388,6 +408,12 @@ func Delete(req SetRequest) (SetResponse, error) {
 	var keys []db.WatchKeys
 	var resp SetResponse
 	path := req.Path
+	if !isAuthorizedForSet(req) {
+		return resp, tlerr.AuthorizationError{
+			Format: "User is unauthorized for Delete Operation",
+			Path: path,
+		}
+	}
 
 	log.Info("Delete request received with path =", path)
 
@@ -398,7 +424,8 @@ func Delete(req SetRequest) (SetResponse, error) {
 		return resp, err
 	}
 
-	err = appInitialize(app, appInfo, path, nil, nil, DELETE)
+	opts := appOptions{deleteEmptyEntry: req.DeleteEmptyEntry}
+	err = appInitialize(app, appInfo, path, nil, &opts, DELETE)
 
 	if err != nil {
 		resp.ErrSrc = AppErr
@@ -454,6 +481,12 @@ func Get(req GetRequest) (GetResponse, error) {
 	var payload []byte
 	var resp GetResponse
 	path := req.Path
+	if !isAuthorizedForGet(req) {
+		return resp, tlerr.AuthorizationError{
+			Format: "User is unauthorized for Get Operation",
+			Path: path,
+		}
+	}
 
 	log.Info("Received Get request for path = ", path)
 
@@ -499,6 +532,12 @@ func Action(req ActionRequest) (ActionResponse, error) {
 	var resp ActionResponse
 	path := req.Path
 
+	if !isAuthorizedForAction(req) {
+		return resp, tlerr.AuthorizationError{
+			Format: "User is unauthorized for Action Operation",
+			Path: path,
+		}
+	}
 
 	log.Info("Received Action request for path = ", path)
 
@@ -560,6 +599,13 @@ func Bulk(req BulkRequest) (BulkResponse, error) {
 		UpdateResponse: updateResp,
 		CreateResponse: createResp}
 
+
+    if (!isAuthorizedForBulk(req)) {
+		return resp, tlerr.AuthorizationError{
+			Format: "User is unauthorized for Action Operation",
+		}
+    }
+
 	writeMutex.Lock()
 	defer writeMutex.Unlock()
 
@@ -581,6 +627,7 @@ func Bulk(req BulkRequest) (BulkResponse, error) {
 
 	for i := range req.DeleteRequest {
 		path := req.DeleteRequest[i].Path
+		opts := appOptions{deleteEmptyEntry: req.DeleteRequest[i].DeleteEmptyEntry}
 
 		log.Info("Delete request received with path =", path)
 
@@ -591,7 +638,7 @@ func Bulk(req BulkRequest) (BulkResponse, error) {
 			goto BulkDeleteError
 		}
 
-		err = appInitialize(app, appInfo, path, nil, nil, DELETE)
+		err = appInitialize(app, appInfo, path, nil, &opts, DELETE)
 
 		if err != nil {
 			errSrc = AppErr
@@ -807,6 +854,12 @@ func Subscribe(req SubscribeRequest) ([]*IsSubscribeResponse, error) {
 			Err:                 nil}
 	}
 
+    if (!isAuthorizedForSubscribe(req)) {
+		return resp, tlerr.AuthorizationError{
+			Format: "User is unauthorized for Action Operation",
+		}
+    }
+
 	isGetCase := true
 	dbs, err := getAllDbs(isGetCase)
 
@@ -903,6 +956,12 @@ func IsSubscribeSupported(req IsSubscribeRequest) ([]*IsSubscribeResponse, error
 			Err:                 nil}
 	}
 
+    if (!isAuthorizedForIsSubscribe(req)) {
+		return resp, tlerr.AuthorizationError{
+			Format: "User is unauthorized for Action Operation",
+		}
+    }
+
 	isGetCase := true
 	dbs, err := getAllDbs(isGetCase)
 
@@ -1075,7 +1134,7 @@ func getDBOptionsWithSeparator(dbNo db.DBNum, initIndicator string, tableSeparat
 		InitIndicator:      initIndicator,
 		TableNameSeparator: tableSeparator,
 		KeySeparator:       keySeparator,
-		//IsWriteDisabled:    isWriteDisabled, //Will be enabled once the DB access layer changes are checked in
+		IsWriteDisabled:    isWriteDisabled,
 	})
 }
 
@@ -1088,6 +1147,10 @@ func getAppModule(path string, clientVer Version) (*appInterface, *appInfo, erro
 		return nil, aInfo, err
 	}
 
+	if err := validateClientVersion(clientVer, path, aInfo); err != nil {
+		return nil, aInfo, err
+	}
+
 	app, err = getAppInterface(aInfo.appType)
 
 	if err != nil {
diff --git a/translib/version.go b/translib/version.go
index c066cfcba19a..4676a2703457 100644
--- a/translib/version.go
+++ b/translib/version.go
@@ -1,7 +1,31 @@
+////////////////////////////////////////////////////////////////////////////////
+//                                                                            //
+//  Copyright 2020 Broadcom. The term Broadcom refers to Broadcom Inc. and/or //
+//  its subsidiaries.                                                         //
+//                                                                            //
+//  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 translib
 
 import (
-    "fmt"
+	"encoding/xml"
+	"fmt"
+	"os"
+	"path/filepath"
+	"github.com/Azure/sonic-mgmt-common/translib/tlerr"
+	"github.com/golang/glog"
 )
 
 // theYangBundleVersion indicates the current yang bundle version.
@@ -16,24 +40,144 @@ var theYangBaseVersion Version
 // Version represents the semantic version number in Major.Minor.Patch
 // format.
 type Version struct {
-    Major uint32 // Major version number
-    Minor uint32 // Minor version number
-    Patch uint32 // Patch number
+	Major uint32 // Major version number
+	Minor uint32 // Minor version number
+	Patch uint32 // Patch number
 }
 
 // NewVersion creates a Version object from given version string
 func NewVersion(s string) (Version, error) {
-    var v Version
-    err := v.Set(s)
-    return v, err 
+	var v Version
+	err := v.Set(s)
+	return v, err
+}
+
+func (v Version) String() string {
+	return fmt.Sprintf("%d.%d.%d", v.Major, v.Minor, v.Patch)
 }
 
 // Set parses a version string in X.Y.Z into a Version object v.
 func (v *Version) Set(s string) error {
-    _, err := fmt.Sscanf(s, "%d.%d.%d", &v.Major, &v.Minor, &v.Patch)
-    if err == nil {
-        err = fmt.Errorf("Invalid version \"%s\"", s)
-    }   
+	_, err := fmt.Sscanf(s, "%d.%d.%d", &v.Major, &v.Minor, &v.Patch)
+	if err == nil && v.IsNull() {
+		err = fmt.Errorf("Invalid version \"%s\"", s)
+	}
+
+	return err
+}
+
+// IsNull checks if the version v is a null version (0.0.0)
+func (v *Version) IsNull() bool {
+	return v == nil || (v.Major == 0 && v.Minor == 0 && v.Patch == 0)
+}
+
+// GreaterThan checks if the Version v is more than another version
+func (v *Version) GreaterThan(other Version) bool {
+	return (v.Major > other.Major) ||
+		(v.Major == other.Major && v.Minor > other.Minor) ||
+		(v.Major == other.Major && v.Minor == other.Minor && v.Patch > other.Patch)
+}
+
+// GetCompatibleBaseVersion returns the compatible base version for
+// current version.
+func (v *Version) GetCompatibleBaseVersion() Version {
+	switch v.Major {
+	case 0:
+		// 0.x.x versions are always considered as developement versions
+		// and are not backward compatible. So, base = current
+		return *v
+	case 1:
+		// Base is 1.0.0 if yang bundle version is 1.x.x
+		return Version{Major: 1}
+	default:
+		// For 2.x.x or higher versions the base will be (N-1).0.0
+		return Version{Major: v.Major - 1}
+	}
+}
+
+// validateClientVersion verifies API client client is compatible with this server.
+func validateClientVersion(clientVer Version, path string, appInfo *appInfo) error {
+	if clientVer.IsNull() {
+		// Client did not povide version info
+		return nil
+	}
+
+	if appInfo.isNative {
+		return validateClientVersionForNonYangAPI(clientVer, path, appInfo)
+	}
+
+	return validateClientVersionForYangAPI(clientVer, path, appInfo)
+}
+
+// validateClientVersionForYangAPI checks theYangBaseVersion <= clientVer <= theYangBundleVersion
+func validateClientVersionForYangAPI(clientVer Version, path string, appInfo *appInfo) error {
+	if theYangBaseVersion.GreaterThan(clientVer) {
+		glog.Errorf("Client version %s is less than base version %s", clientVer, theYangBaseVersion)
+	} else if clientVer.GreaterThan(theYangBundleVersion) {
+		glog.Errorf("Client version %s is more than server vesion %s", clientVer, theYangBundleVersion)
+	} else {
+		return nil
+	}
+
+	return tlerr.TranslibUnsupportedClientVersion{
+		ClientVersion:     clientVer.String(),
+		ServerVersion:     theYangBundleVersion.String(),
+		ServerBaseVersion: theYangBaseVersion.String(),
+	}
+}
+
+// validateClientVersionForNonYangAPI checks client version for non-yang APIs
+func validateClientVersionForNonYangAPI(clientVer Version, path string, appInfo *appInfo) error {
+	// Version checks are not supported for non-yang APIs.
+	// Client versions are ignored.
+	return nil
+}
+
+//========= initialization =========
+
+func init() {
+	path := filepath.Join(GetYangPath(), "version.xml")
+	if err := initYangVersionConfigFromFile(path); err != nil {
+		glog.Errorf("Error loading version config file; err=%v", err)
+		glog.Errorf("API VERSION CHECK IS DISABLED")
+	} else {
+		glog.Infof("*** Yang bundle version = %s", theYangBundleVersion)
+		glog.Infof("*** Yang base version   = %s", theYangBaseVersion)
+	}
+}
+
+// Load version config from file
+func initYangVersionConfigFromFile(path string) error {
+	f, err := os.Open(path)
+	if err != nil {
+		return err
+	}
+
+	defer f.Close()
+
+	var configData struct {
+		YangBundleVersion Version `xml:"yang-bundle-version"`
+	}
+
+	err = xml.NewDecoder(f).Decode(&configData)
+	if err != nil {
+		return err
+	}
+
+	theYangBundleVersion = configData.YangBundleVersion
+	theYangBaseVersion = theYangBundleVersion.GetCompatibleBaseVersion()
+
+	return nil
+}
+
+// GetYangBundleVersion returns the API version for yang bundle hosted
+// on this server.
+func GetYangBundleVersion() Version {
+	return theYangBundleVersion
+}
 
-    return err 
+// GetYangBaseVersion returns the base version or min version of yang APIs
+// supported by this server.
+func GetYangBaseVersion() Version {
+	return theYangBaseVersion
 }
diff --git a/translib/version_test.go b/translib/version_test.go
new file mode 100755
index 000000000000..eb9a093f2d10
--- /dev/null
+++ b/translib/version_test.go
@@ -0,0 +1,226 @@
+////////////////////////////////////////////////////////////////////////////////
+//                                                                            //
+//  Copyright 2020 Broadcom. The term Broadcom refers to Broadcom Inc. and/or //
+//  its subsidiaries.                                                         //
+//                                                                            //
+//  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 translib
+
+import (
+	"fmt"
+	"testing"
+	"github.com/Azure/sonic-mgmt-common/translib/tlerr"
+)
+
+func ver(major, minor, patch uint32) Version {
+	return Version{Major: major, Minor: minor, Patch: patch}
+}
+
+func TestVersionParseStr(t *testing.T) {
+	t.Run("empty", testVerSet("", ver(0, 0, 0), false))
+	t.Run("0.0.0", testVerSet("0.0.0", ver(0, 0, 0), false))
+	t.Run("1.0.0", testVerSet("1.0.0", ver(1, 0, 0), true))
+	t.Run("1.2.3", testVerSet("1.2.3", ver(1, 2, 3), true))
+	t.Run("1.-.-", testVerSet("1", Version{}, false))
+	t.Run("1.2.-", testVerSet("1.2", Version{}, false))
+	t.Run("1.-.3", testVerSet("1..2", Version{}, false))
+	t.Run("neg_majr", testVerSet("-1.0.0", Version{}, false))
+	t.Run("bad_majr", testVerSet("A.2.3", Version{}, false))
+	t.Run("neg_minr", testVerSet("1.-2.0", Version{}, false))
+	t.Run("bad_minr", testVerSet("1.B.3", Version{}, false))
+	t.Run("neg_pat", testVerSet("1.2.-3", Version{}, false))
+	t.Run("bad_pat", testVerSet("1.2.C", Version{}, false))
+	t.Run("invalid", testVerSet("invalid", Version{}, false))
+}
+
+func testVerSet(vStr string, exp Version, expSuccess bool) func(*testing.T) {
+	return func(t *testing.T) {
+		v, err := NewVersion(vStr)
+		if err != nil {
+			if expSuccess == true {
+				t.Fatalf("Failed to parse \"%s\"; err=%v. Expected %v", vStr, err, exp)
+			}
+			return
+		}
+
+		if !expSuccess {
+			t.Fatalf("Version string \"%s\" was expected to fail; but got %v", vStr, v)
+		}
+
+		if v != exp {
+			t.Fatalf("Failed to parse \"%s\"; expected %v", vStr, v)
+		}
+	}
+}
+
+func TestVersionGetBase(t *testing.T) {
+	t.Run("0.0.0", testGetBase(ver(0, 0, 0), ver(0, 0, 0)))
+	t.Run("0.0.1", testGetBase(ver(0, 0, 1), ver(0, 0, 1)))
+	t.Run("0.1.2", testGetBase(ver(0, 1, 2), ver(0, 1, 2)))
+	t.Run("1.0.0", testGetBase(ver(1, 0, 0), ver(1, 0, 0)))
+	t.Run("1.0.1", testGetBase(ver(1, 0, 1), ver(1, 0, 0)))
+	t.Run("1.2.1", testGetBase(ver(1, 2, 1), ver(1, 0, 0)))
+	t.Run("2.0.0", testGetBase(ver(2, 0, 0), ver(1, 0, 0)))
+	t.Run("2.3.4", testGetBase(ver(2, 3, 4), ver(1, 0, 0)))
+	t.Run("3.0.0", testGetBase(ver(5, 6, 7), ver(4, 0, 0)))
+}
+
+func testGetBase(v, expBase Version) func(*testing.T) {
+	return func(t *testing.T) {
+		base := v.GetCompatibleBaseVersion()
+		if base != expBase {
+			t.Fatalf("Got base of %s as %s; expected %s", v, base, expBase)
+		}
+	}
+}
+
+func setYangBundleVersion(v Version) {
+	theYangBundleVersion = v
+	theYangBaseVersion = v.GetCompatibleBaseVersion()
+}
+
+func TestVersionCheck(t *testing.T) {
+	// Set yang bundle version tp 2.3.4 and try various ClientVersion
+	testVer, _ := NewVersion("2.3.4")
+	origVer := theYangBundleVersion
+	setYangBundleVersion(testVer)
+	defer setYangBundleVersion(origVer) // restore original version
+
+	testVCheck(t, "", true)
+	testVCheck(t, "0.0.9", false)
+	testVCheck(t, "0.9.9", false)
+	testVCheck(t, "1.0.0", true)
+	testVCheck(t, "1.2.3", true)
+	testVCheck(t, "2.0.0", true)
+	testVCheck(t, "2.1.9", true)
+	testVCheck(t, "2.3.2", true)
+	testVCheck(t, "2.3.4", true)
+	testVCheck(t, "2.3.9", false)
+	testVCheck(t, "2.4.0", false)
+	testVCheck(t, "3.0.0", false)
+}
+
+func testVCheck(t *testing.T, ver string, expSuccess bool) {
+	v, err := NewVersion(ver)
+	if ver != "" && err != nil {
+		t.Fatalf("Bad version \"%s\"", ver)
+	}
+
+	t.Run(fmt.Sprintf("get_%s", ver), vGet(v, expSuccess))
+	t.Run(fmt.Sprintf("create_%s", ver), vCreate(v, expSuccess))
+	t.Run(fmt.Sprintf("update_%s", ver), vUpdate(v, expSuccess))
+	t.Run(fmt.Sprintf("delete_%s", ver), vDelete(v, expSuccess))
+	t.Run(fmt.Sprintf("replace_%s", ver), vReplace(v, expSuccess))
+	t.Run(fmt.Sprintf("action_%s", ver), vAction(v, expSuccess))
+	t.Run(fmt.Sprintf("subs_%s", ver), vSubscribe(v, expSuccess))
+	t.Run(fmt.Sprintf("is_subs_%s", ver), vIsSubscribe(v, expSuccess))
+}
+
+var (
+	tPath = "/openconfig-acl:acl"
+	tBody = []byte("{}")
+)
+
+func vCreate(v Version, expSuccess bool) func(*testing.T) {
+	return func(t *testing.T) {
+		_, err := Create(SetRequest{Path:tPath, Payload:tBody, ClientVersion: v})
+		checkErr(t, err, expSuccess)
+	}
+}
+
+func vUpdate(v Version, expSuccess bool) func(*testing.T) {
+	return func(t *testing.T) {
+		_, err := Update(SetRequest{Path:tPath, Payload:tBody, ClientVersion: v})
+		checkErr(t, err, expSuccess)
+	}
+}
+
+func vReplace(v Version, expSuccess bool) func(*testing.T) {
+	return func(t *testing.T) {
+		_, err := Replace(SetRequest{Path:tPath, Payload:tBody, ClientVersion: v})
+		checkErr(t, err, expSuccess)
+	}
+}
+
+func vDelete(v Version, expSuccess bool) func(*testing.T) {
+	return func(t *testing.T) {
+		_, err := Delete(SetRequest{Path:tPath, ClientVersion: v})
+		checkErr(t, err, expSuccess)
+	}
+}
+
+func vGet(v Version, expSuccess bool) func(*testing.T) {
+	return func(t *testing.T) {
+		_, err := Get(GetRequest{Path: tPath, ClientVersion: v})
+		checkErr(t, err, expSuccess)
+	}
+}
+
+func vAction(v Version, expSuccess bool) func(*testing.T) {
+	return func(t *testing.T) {
+		_, err := Action(ActionRequest{Path: tPath, ClientVersion: v})
+		checkErr(t, ignoreNotImpl(err), expSuccess)
+	}
+}
+
+func vSubscribe(v Version, expSuccess bool) func(*testing.T) {
+	return func(t *testing.T) {
+		_, err := Subscribe(SubscribeRequest{Paths: []string{tPath}, ClientVersion: v})
+		checkErr(t, ignoreNotImpl(err), expSuccess)
+	}
+}
+
+func vIsSubscribe(v Version, expSuccess bool) func(*testing.T) {
+	return func(t *testing.T) {
+		req := IsSubscribeRequest{Paths: []string{tPath}, ClientVersion: v}
+		resp, err := IsSubscribeSupported(req)
+		if err == nil && len(resp) == 1 && resp[0].Err != nil {
+			err = resp[0].Err
+		}
+		checkErr(t, ignoreNotImpl(err), expSuccess)
+	}
+}
+
+func isVersionError(err error) bool {
+	if _, ok := err.(tlerr.TranslibUnsupportedClientVersion); ok {
+		return true
+	}
+	return false
+}
+
+func checkErr(t *testing.T, err error, expSuccess bool) {
+	if expSuccess && err != nil {
+		t.Fatalf("Unexpected %T %v", err, err)
+	}
+	if !expSuccess && !isVersionError(err) {
+		t.Fatalf("Unexpected %T %v; expected TranslibUnsupportedClientVersion", err, err)
+	}
+}
+
+func ignoreNotImpl(err error) error {
+	switch err.(type) {
+	case nil:
+		return nil
+	case tlerr.NotSupportedError:
+		return nil
+	default:
+		e := err.Error()
+		if e == "Not supported" || e == "Not implemented" {
+			return nil
+		}
+	}
+	return err
+}
diff --git a/translib/yanglib_app.go b/translib/yanglib_app.go
index c235a97677e0..9168eb5a1fbf 100644
--- a/translib/yanglib_app.go
+++ b/translib/yanglib_app.go
@@ -508,5 +508,5 @@ func GetYangPath() string {
 
 // GetYangModuleSetID returns the ietf-yang-library's module-set-id value.
 func GetYangModuleSetID() string {
-	return "0.1.0" //FIXME use YangBundleVersion when API versioning is available.
+	return GetYangBundleVersion().String()
 }