Updating "primary" to "default" for rule-based
diff --git a/docs/userguide/dev/codingguidelines.md b/docs/userguide/dev/codingguidelines.md
index c702dea..b76b5ab 100644
--- a/docs/userguide/dev/codingguidelines.md
+++ b/docs/userguide/dev/codingguidelines.md
@@ -1907,7 +1907,7 @@
 
 Most of the data items are pre-built into binary files that are then installed
 on a user's machine. Some data can also be built at runtime but is not
-persistent. In the latter case, a master object should be built once and then
+persistent. In the latter case, a primary object should be built once and then
 cloned to avoid the multiple parsing, processing, and building of the same data.
 
 Binary data formats for ICU must be portable across platforms that share the
diff --git a/icu4c/source/Doxyfile.in b/icu4c/source/Doxyfile.in
index 25b535c..7ced104 100644
--- a/icu4c/source/Doxyfile.in
+++ b/icu4c/source/Doxyfile.in
@@ -1310,7 +1310,7 @@
 HHC_LOCATION           =
 
 # The GENERATE_CHI flag controls if a separate .chi index file is generated
-# (YES) or that it should be included in the master .chm file (NO).
+# (YES) or that it should be included in the primary .chm file (NO).
 # The default value is: NO.
 # This tag requires that the tag GENERATE_HTMLHELP is set to YES.
 
diff --git a/icu4c/source/common/locid.cpp b/icu4c/source/common/locid.cpp
index 19b61cd..a2c38a9 100644
--- a/icu4c/source/common/locid.cpp
+++ b/icu4c/source/common/locid.cpp
@@ -1025,13 +1025,14 @@
         return result;
     }
 
-    // If a BCP-47 language tag is passed as the language parameter to the
+    // If a BCP 47 language tag is passed as the language parameter to the
     // normal Locale constructor, it will actually fall back to invoking
     // uloc_forLanguageTag() to parse it if it somehow is able to detect that
-    // the string actually is BCP-47. This works well for things like strings
-    // using BCP-47 extensions, but it does not at all work for things like
-    // BCP-47 grandfathered tags (eg. "en-GB-oed") which are possible to also
-    // interpret as ICU locale IDs and because of that won't trigger the BCP-47
+    // the string actually is BCP 47. This works well for things like strings
+    // using BCP 47 extensions, but it does not at all work for things like
+    // legacy language tags (marked as “Type: grandfathered” in BCP 47,
+    // e.g., "en-GB-oed") which are possible to also
+    // interpret as ICU locale IDs and because of that won't trigger the BCP 47
     // parsing. Therefore the code here explicitly calls uloc_forLanguageTag()
     // and then Locale::init(), instead of just calling the normal constructor.
 
diff --git a/icu4c/source/common/uloc_tag.cpp b/icu4c/source/common/uloc_tag.cpp
index ad5dd64..5eed02c 100644
--- a/icu4c/source/common/uloc_tag.cpp
+++ b/icu4c/source/common/uloc_tag.cpp
@@ -53,7 +53,7 @@
     VariantListEntry    *variants;
     ExtensionListEntry  *extensions;
     const char          *privateuse;
-    const char          *grandfathered;
+    const char          *legacy;
 } ULanguageTag;
 
 #define MINLEN 2
@@ -85,8 +85,9 @@
  Updated on 2018-09-12 from
  https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry .
 
- This table has 2 parts. The parts for Grandfathered tags is generated by the
- following scripts from the IANA language tag registry.
+ This table has 2 parts. The part for
+ legacy language tags (marked as “Type: grandfathered” in BCP 47)
+ is generated by the following scripts from the IANA language tag registry.
 
  curl  https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry |\
  egrep -A 7 'Type: grandfathered' | \
@@ -100,8 +101,8 @@
  values. They may have to be removed for the strict BCP 47 compliance.
 
 */
-static const char* const GRANDFATHERED[] = {
-/*  grandfathered   preferred */
+static const char* const LEGACY[] = {
+/*  legacy          preferred */
     "art-lojban",   "jbo",
     "en-gb-oed",    "en-gb-oxendict",
     "i-ami",        "ami",
@@ -124,7 +125,7 @@
     "zh-min-nan",   "nan",
     "zh-xiang",     "hsn",
 
-    // Grandfathered tags with no preferred value in the IANA
+    // Legacy tags with no preferred value in the IANA
     // registry. Kept for now for the backward compatibility
     // because ICU has mapped them this way.
     "cel-gaulish",  "xtg-x-cel-gaulish",
@@ -346,7 +347,7 @@
 
 #if 0
 static const char*
-ultag_getGrandfathered(const ULanguageTag* langtag);
+ultag_getLegacy(const ULanguageTag* langtag);
 #endif
 
 U_NAMESPACE_BEGIN
@@ -986,7 +987,7 @@
     langtag->variants = NULL;
     langtag->extensions = NULL;
 
-    langtag->grandfathered = EMPTY;
+    langtag->legacy = EMPTY;
     langtag->privateuse = EMPTY;
 }
 
@@ -2042,7 +2043,7 @@
     char *pExtValueSubtag, *pExtValueSubtagEnd;
     int32_t i;
     UBool privateuseVar = FALSE;
-    int32_t grandfatheredLen = 0;
+    int32_t legacyLen = 0;
 
     if (parsedLen != NULL) {
         *parsedLen = 0;
@@ -2082,25 +2083,25 @@
     }
 
     size_t parsedLenDelta = 0;
-    // Grandfathered tag will be consider together. Grandfathered tag with intervening
+    // Legacy tag will be consider together. Legacy tag with intervening
     // script and region such as art-DE-lojban or art-Latn-lojban won't be
     // matched.
-    /* check if the tag is grandfathered */
-    for (i = 0; i < UPRV_LENGTHOF(GRANDFATHERED); i += 2) {
-        int32_t checkGrandfatheredLen = static_cast<int32_t>(uprv_strlen(GRANDFATHERED[i]));
-        if (tagLen < checkGrandfatheredLen) {
+    /* check if the tag is legacy */
+    for (i = 0; i < UPRV_LENGTHOF(LEGACY); i += 2) {
+        int32_t checkLegacyLen = static_cast<int32_t>(uprv_strlen(LEGACY[i]));
+        if (tagLen < checkLegacyLen) {
             continue;
         }
-        if (tagLen > checkGrandfatheredLen && tagBuf[checkGrandfatheredLen] != '-') {
+        if (tagLen > checkLegacyLen && tagBuf[checkLegacyLen] != '-') {
             // make sure next char is '-'.
             continue;
         }
-        if (uprv_strnicmp(GRANDFATHERED[i], tagBuf, checkGrandfatheredLen) == 0) {
+        if (uprv_strnicmp(LEGACY[i], tagBuf, checkLegacyLen) == 0) {
             int32_t newTagLength;
 
-            grandfatheredLen = checkGrandfatheredLen;  /* back up for output parsedLen */
-            int32_t replacementLen = static_cast<int32_t>(uprv_strlen(GRANDFATHERED[i+1]));
-            newTagLength = replacementLen + tagLen - checkGrandfatheredLen;
+            legacyLen = checkLegacyLen;  /* back up for output parsedLen */
+            int32_t replacementLen = static_cast<int32_t>(uprv_strlen(LEGACY[i+1]));
+            newTagLength = replacementLen + tagLen - checkLegacyLen;
             if (tagLen < newTagLength) {
                 uprv_free(tagBuf);
                 tagBuf = (char*)uprv_malloc(newTagLength + 1);
@@ -2111,16 +2112,16 @@
                 t->buf = tagBuf;
                 tagLen = newTagLength;
             }
-            parsedLenDelta = checkGrandfatheredLen - replacementLen;
-            uprv_strcpy(t->buf, GRANDFATHERED[i + 1]);
-            if (checkGrandfatheredLen != tagLen) {
-                uprv_strcpy(t->buf + replacementLen, tag + checkGrandfatheredLen);
+            parsedLenDelta = checkLegacyLen - replacementLen;
+            uprv_strcpy(t->buf, LEGACY[i + 1]);
+            if (checkLegacyLen != tagLen) {
+                uprv_strcpy(t->buf + replacementLen, tag + checkLegacyLen);
             }
             break;
         }
     }
 
-    if (grandfatheredLen == 0) {
+    if (legacyLen == 0) {
         for (i = 0; i < UPRV_LENGTHOF(REDUNDANT); i += 2) {
             const char* redundantTag = REDUNDANT[i];
             size_t redundantTagLen = uprv_strlen(redundantTag);
@@ -2608,8 +2609,8 @@
 
 #if 0
 static const char*
-ultag_getGrandfathered(const ULanguageTag* langtag) {
-    return langtag->grandfathered;
+ultag_getLegacy(const ULanguageTag* langtag) {
+    return langtag->legacy;
 }
 #endif
 
diff --git a/icu4c/source/common/ulocimp.h b/icu4c/source/common/ulocimp.h
index b4d64c5..cd5a357 100644
--- a/icu4c/source/common/ulocimp.h
+++ b/icu4c/source/common/ulocimp.h
@@ -109,13 +109,17 @@
  * If the specified language tag contains any ill-formed subtags,
  * the first such subtag and all following subtags are ignored.
  * <p>
- * This implements the 'Language-Tag' production of BCP47, and so
- * supports grandfathered (regular and irregular) as well as private
- * use language tags.  Private use tags are represented as 'x-whatever',
- * and grandfathered tags are converted to their canonical replacements
- * where they exist.  Note that a few grandfathered tags have no modern
- * replacement, these will be converted using the fallback described in
+ * This implements the 'Language-Tag' production of BCP 47, and so
+ * supports legacy language tags (marked as “Type: grandfathered” in BCP 47)
+ * (regular and irregular) as well as private use language tags.
+ *
+ * Private use tags are represented as 'x-whatever',
+ * and legacy tags are converted to their canonical replacements where they exist.
+ *
+ * Note that a few legacy tags have no modern replacement;
+ * these will be converted using the fallback described in
  * the first paragraph, so some information might be lost.
+ *
  * @param langtag   the input BCP47 language tag.
  * @param tagLen    the length of langtag, or -1 to call uprv_strlen().
  * @param sink      the output sink receiving a locale ID for the
diff --git a/icu4c/source/common/unicode/localebuilder.h b/icu4c/source/common/unicode/localebuilder.h
index c5836fe..664ee6a 100644
--- a/icu4c/source/common/unicode/localebuilder.h
+++ b/icu4c/source/common/unicode/localebuilder.h
@@ -92,11 +92,12 @@
     /**
      * Resets the LocaleBuilder to match the provided
      * [Unicode Locale Identifier](http://www.unicode.org/reports/tr35/tr35.html#unicode_locale_id) .
-     * Discards the existing state. the empty string cause the builder to be
-     * reset, like {@link #clear}.  Grandfathered tags are converted to their
-     * canonical form before being processed.  Otherwise, the <code>language
-     * tag</code> must be well-formed, or else the build() method will later
-     * report an U_ILLEGAL_ARGUMENT_ERROR.
+     * Discards the existing state.
+     * The empty string causes the builder to be reset, like {@link #clear}.
+     * Legacy language tags (marked as “Type: grandfathered” in BCP 47)
+     * are converted to their canonical form before being processed.
+     * Otherwise, the <code>language tag</code> must be well-formed,
+     * or else the build() method will later report an U_ILLEGAL_ARGUMENT_ERROR.
      *
      * <p>This method clears the internal UErrorCode.
      *
diff --git a/icu4c/source/common/unicode/locid.h b/icu4c/source/common/unicode/locid.h
index 1d031da..f955743 100644
--- a/icu4c/source/common/unicode/locid.h
+++ b/icu4c/source/common/unicode/locid.h
@@ -393,13 +393,17 @@
      * If the specified language tag contains any ill-formed subtags,
      * the first such subtag and all following subtags are ignored.
      * <p>
-     * This implements the 'Language-Tag' production of BCP47, and so
-     * supports grandfathered (regular and irregular) as well as private
-     * use language tags.  Private use tags are represented as 'x-whatever',
-     * and grandfathered tags are converted to their canonical replacements
-     * where they exist.  Note that a few grandfathered tags have no modern
-     * replacement, these will be converted using the fallback described in
+     * This implements the 'Language-Tag' production of BCP 47, and so
+     * supports legacy language tags (marked as “Type: grandfathered” in BCP 47)
+     * (regular and irregular) as well as private use language tags.
+     *
+     * Private use tags are represented as 'x-whatever',
+     * and legacy tags are converted to their canonical replacements where they exist.
+     *
+     * Note that a few legacy tags have no modern replacement;
+     * these will be converted using the fallback described in
      * the first paragraph, so some information might be lost.
+     *
      * @param tag     the input BCP47 language tag.
      * @param status  error information if creating the Locale failed.
      * @return        the Locale for the specified BCP47 language tag.
diff --git a/icu4c/source/common/unicode/ucnv.h b/icu4c/source/common/unicode/ucnv.h
index ec7c5f3..614001c 100644
--- a/icu4c/source/common/unicode/ucnv.h
+++ b/icu4c/source/common/unicode/ucnv.h
@@ -476,7 +476,7 @@
  * <p>The name will NOT be looked up in the alias mechanism, nor will the converter be
  * stored in the converter cache or the alias table. The only way to open further converters
  * is call this function multiple times, or use the ucnv_safeClone() function to clone a
- * 'master' converter.</p>
+ * 'primary' converter.</p>
  *
  * <p>A future version of ICU may add alias table lookups and/or caching
  * to this function.</p>
diff --git a/icu4c/source/common/unicode/uloc.h b/icu4c/source/common/unicode/uloc.h
index d3de89f..fa38092 100644
--- a/icu4c/source/common/unicode/uloc.h
+++ b/icu4c/source/common/unicode/uloc.h
@@ -1237,14 +1237,18 @@
  * Returns a locale ID for the specified BCP47 language tag string.
  * If the specified language tag contains any ill-formed subtags,
  * the first such subtag and all following subtags are ignored.
- * <p> 
- * This implements the 'Language-Tag' production of BCP47, and so
- * supports grandfathered (regular and irregular) as well as private
- * use language tags.  Private use tags are represented as 'x-whatever',
- * and grandfathered tags are converted to their canonical replacements
- * where they exist.  Note that a few grandfathered tags have no modern
- * replacement, these will be converted using the fallback described in
+ * <p>
+ * This implements the 'Language-Tag' production of BCP 47, and so
+ * supports legacy language tags (marked as “Type: grandfathered” in BCP 47)
+ * (regular and irregular) as well as private use language tags.
+ *
+ * Private use tags are represented as 'x-whatever',
+ * and legacy tags are converted to their canonical replacements where they exist.
+ *
+ * Note that a few legacy tags have no modern replacement;
+ * these will be converted using the fallback described in
  * the first paragraph, so some information might be lost.
+ *
  * @param langtag   the input BCP47 language tag.
  * @param localeID  the output buffer receiving a locale ID for the
  *                  specified BCP47 language tag.
diff --git a/icu4c/source/common/unifiedcache.cpp b/icu4c/source/common/unifiedcache.cpp
index f2dd916..493ab79 100644
--- a/icu4c/source/common/unifiedcache.cpp
+++ b/icu4c/source/common/unifiedcache.cpp
@@ -311,7 +311,7 @@
     }
     keyToAdopt->fCreationStatus = creationStatus;
     if (value->softRefCount == 0) {
-        _registerMaster(keyToAdopt, value);
+        _registerPrimary(keyToAdopt, value);
     }
     void *oldValue = uhash_put(fHashtable, keyToAdopt, (void *) value, &status);
     U_ASSERT(oldValue == nullptr);
@@ -338,7 +338,7 @@
     } else {
         _put(element, value, status);
     }
-    // Run an eviction slice. This will run even if we added a master entry
+    // Run an eviction slice. This will run even if we added a primary entry
     // which doesn't increase the unused count, but that is still o.k
     _runEvictionSlice();
 }
@@ -403,9 +403,9 @@
     }
 }
 
-void UnifiedCache::_registerMaster(
+void UnifiedCache::_registerPrimary(
             const CacheKeyBase *theKey, const SharedObject *value) const {
-    theKey->fIsMaster = true;
+    theKey->fIsPrimary = true;
     value->cachePtr = this;
     ++fNumValuesTotal;
     ++fNumValuesInUse;
@@ -420,7 +420,7 @@
     const SharedObject *oldValue = (const SharedObject *) element->value.pointer;
     theKey->fCreationStatus = status;
     if (value->softRefCount == 0) {
-        _registerMaster(theKey, value);
+        _registerPrimary(theKey, value);
     }
     value->softRefCount++;
     UHashElement *ptr = const_cast<UHashElement *>(element);
@@ -474,9 +474,9 @@
         return FALSE;
     }
 
-    // We can evict entries that are either not a master or have just
+    // We can evict entries that are either not a primary or have just
     // one reference (The one reference being from the cache itself).
-    return (!theKey->fIsMaster || (theValue->softRefCount == 1 && theValue->noHardReferences()));
+    return (!theKey->fIsPrimary || (theValue->softRefCount == 1 && theValue->noHardReferences()));
 }
 
 void UnifiedCache::removeSoftRef(const SharedObject *value) const {
diff --git a/icu4c/source/common/unifiedcache.h b/icu4c/source/common/unifiedcache.h
index d6c9945..6bb46a5 100644
--- a/icu4c/source/common/unifiedcache.h
+++ b/icu4c/source/common/unifiedcache.h
@@ -34,13 +34,13 @@
  */
 class U_COMMON_API CacheKeyBase : public UObject {
  public:
-   CacheKeyBase() : fCreationStatus(U_ZERO_ERROR), fIsMaster(FALSE) {}
+   CacheKeyBase() : fCreationStatus(U_ZERO_ERROR), fIsPrimary(FALSE) {}
 
    /**
     * Copy constructor. Needed to support cloning.
     */
    CacheKeyBase(const CacheKeyBase &other) 
-           : UObject(other), fCreationStatus(other.fCreationStatus), fIsMaster(FALSE) { }
+           : UObject(other), fCreationStatus(other.fCreationStatus), fIsPrimary(FALSE) { }
    virtual ~CacheKeyBase();
 
    /**
@@ -88,7 +88,7 @@
    }
  private:
    mutable UErrorCode fCreationStatus;
-   mutable UBool fIsMaster;
+   mutable UBool fIsPrimary;
    friend class UnifiedCache;
 };
 
@@ -463,17 +463,17 @@
    void _runEvictionSlice() const;
  
    /**
-    * Register a master cache entry. A master key is the first key to create
+    * Register a primary cache entry. A primary key is the first key to create
     * a given  SharedObject value. Subsequent keys whose create function
-    * produce referneces to an already existing SharedObject are not masters -
+    * produce referneces to an already existing SharedObject are not primary -
     * they can be evicted and subsequently recreated.
     * 
     * On entry, gCacheMutex must be held.
-    * On exit, items in use count incremented, entry is marked as a master
+    * On exit, items in use count incremented, entry is marked as a primary
     * entry, and value registered with cache so that subsequent calls to
     * addRef() and removeRef() on it correctly interact with the cache.
     */
-   void _registerMaster(const CacheKeyBase *theKey, const SharedObject *value) const;
+   void _registerPrimary(const CacheKeyBase *theKey, const SharedObject *value) const;
         
    /**
     * Store a value and creation error status in given hash entry.
diff --git a/icu4c/source/data/cldr-icu-readme.txt b/icu4c/source/data/cldr-icu-readme.txt
index 701ba98..9cb9032 100644
--- a/icu4c/source/data/cldr-icu-readme.txt
+++ b/icu4c/source/data/cldr-icu-readme.txt
@@ -226,7 +226,7 @@
 # Repeat steps 4-7 until there are no errors.
 
 # 9. You can also run the make check tests in exhaustive mode (these will also
-# be run automatically on the master branch after the merge resulting from this
+# be run automatically on the primarys branch after the merge resulting from this
 # integration):
 
 cd $ICU4C_DIR/source
diff --git "a/icu4c/source/i18n/\043nfrs.h\043" "b/icu4c/source/i18n/\043nfrs.h\043"
new file mode 100644
index 0000000..db03c90
--- /dev/null
+++ "b/icu4c/source/i18n/\043nfrs.h\043"
@@ -0,0 +1,111 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+/*
+******************************************************************************
+*   Copyright (C) 1997-2015, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+******************************************************************************
+*   file name:  nfrs.h
+*   encoding:   UTF-8
+*   tab size:   8 (not used)
+*   indentation:4
+*
+* Modification history
+* Date        Name      Comments
+* 10/11/2001  Doug      Ported from ICU4J
+*/
+
+#ifndef NFRS_H
+#define NFRS_H
+
+#include "unicode/uobject.h"
+#include "unicode/rbnf.h"
+
+#if U_HAVE_RBNF
+
+#include "unicode/utypes.h"
+#include "unicode/umisc.h"
+
+#include "nfrlist.h"
+
+U_NAMESPACE_BEGIN
+
+class NFRuleSet : public UMemory {
+public:
+    NFRuleSet(RuleBasedNumberFormat *owner, UnicodeString* descriptions, int32_t index, UErrorCode& status);
+    void parseRules(UnicodeString& rules, UErrorCode& status);
+    void setNonNumericalRule(NFRule *rule);
+    void setBestFractionRule(int32_t originalIndex, NFRule *newRule, UBool rememberRule);
+    void makeIntoFractionRuleSet() { fIsFractionRuleSet = TRUE; }
+
+    ~NFRuleSet();
+
+    UBool operator==(const NFRuleSet& rhs) const;
+    UBool operator!=(const NFRuleSet& rhs) const { return !operator==(rhs); }
+
+    UBool isPublic() const { return fIsPublic; }
+
+    UBool isParseable() const { return fIsParseable; }
+
+    UBool isFractionRuleSet() const { return fIsFractionRuleSet; }
+
+    void  getName(UnicodeString& result) const { result.setTo(name); }
+    UBool isNamed(const UnicodeString& _name) const { return this->name == _name; }
+
+    void  format(int64_t number, UnicodeString& toAppendTo, int32_t pos, int32_t recursionCount, UErrorCode& status) const;
+    void  format(double number, UnicodeString& toAppendTo, int32_t pos, int32_t recursionCount, UErrorCode& status) const;
+
+    UBool parse(const UnicodeString& text, ParsePosition& pos, double upperBound, uint32_t nonNumericalExecutedRuleMask, Formattable& result) const;
+
+    void appendRules(UnicodeString& result) const; // toString
+
+    void setDecimalFormatSymbols(const DecimalFormatSymbols &newSymbols, UErrorCode& status);
+
+    const RuleBasedNumberFormat *getOwner() const { return owner; }
+private:
+    const NFRule * findNormalRule(int64_t number) const;
+    const NFRule * findDoubleRule(double number) const;
+    const NFRule * findFractionRuleSetRule(double number) const;
+    
+    friend class NFSubstitution;
+
+private:
+    UnicodeString name;
+    NFRuleList rules;
+    NFRule *nonNumericalRules[6];
+    RuleBasedNumberFormat *owner;
+    NFRuleList fractionRules;
+    UBool fIsFractionRuleSet;
+    UBool fIsPublic;
+    UBool fIsParseable;
+
+    NFRuleSet(const NFRuleSet &other); // forbid copying of this class
+    NFRuleSet &operator=(const NFRuleSet &other); // forbid copying of this class
+};
+
+// utilities from old llong.h
+// convert mantissa portion of double to int64
+int64_t util64_fromDouble(double d);
+
+// raise radix to the power exponent, only non-negative exponents
+// Arithmetic is performed in unsigned space since overflow in
+// signed space is undefined behavior.
+uint64_t util64_pow(uint32_t radix, uint16_t exponent);
+
+// convert n to digit string in buffer, return length of string
+uint32_t util64_tou(int64_t n, UChar* buffer, uint32_t buflen, uint32_t radix = 10, UBool raw = FALSE);
+
+#ifdef RBNF_DEBUG
+int64_t util64_utoi(const UChar* str, uint32_t radix = 10);
+uint32_t util64_toa(int64_t n, char* buffer, uint32_t buflen, uint32_t radix = 10, UBool raw = FALSE);
+int64_t util64_atoi(const char* str, uint32_t radix);
+#endif
+
+
+U_NAMESPACE_END
+
+/* U_HAVE_RBNF */
+#endif
+
+// NFRS_H
+#endif
diff --git a/icu4c/source/i18n/calendar.cpp b/icu4c/source/i18n/calendar.cpp
index 9497a85..c3e5e8c 100644
--- a/icu4c/source/i18n/calendar.cpp
+++ b/icu4c/source/i18n/calendar.cpp
@@ -266,7 +266,7 @@
     //TODO: ULOC_FULL_NAME is out of date and too small..
     char canonicalName[256];
 
-    // canonicalize, so grandfathered variant will be transformed to keywords
+    // Canonicalize, so that an old-style variant will be transformed to keywords.
     // e.g ja_JP_TRADITIONAL -> ja_JP@calendar=japanese
     // NOTE: Since ICU-20187, ja_JP_TRADITIONAL no longer canonicalizes, and
     // the Gregorian calendar is returned instead.
diff --git a/icu4c/source/i18n/fmtable_cnv.cpp b/icu4c/source/i18n/fmtable_cnv.cpp
index 9a64792..bc3847b 100644
--- a/icu4c/source/i18n/fmtable_cnv.cpp
+++ b/icu4c/source/i18n/fmtable_cnv.cpp
@@ -30,8 +30,6 @@
 // -------------------------------------
 // Creates a formattable object with a char* string.
 // This API is useless. The API that takes a UnicodeString is actually just as good.
-// This is just a grandfathered API.
-
 Formattable::Formattable(const char* stringToCopy)
 {
     init();
diff --git a/icu4c/source/i18n/nfrs.cpp b/icu4c/source/i18n/nfrs.cpp
index e7b17b4..1510d88 100644
--- a/icu4c/source/i18n/nfrs.cpp
+++ b/icu4c/source/i18n/nfrs.cpp
@@ -37,7 +37,7 @@
     /** 0.x */
     PROPER_FRACTION_RULE_INDEX = 2,
     /** x.0 */
-    MASTER_RULE_INDEX = 3,
+    DEFAULT_RULE_INDEX = 3,
     /** Inf */
     INFINITY_RULE_INDEX = 4,
     /** NaN */
@@ -278,8 +278,8 @@
     else if (baseValue == NFRule::kProperFractionRule) {
         setBestFractionRule(PROPER_FRACTION_RULE_INDEX, rule, TRUE);
     }
-    else if (baseValue == NFRule::kMasterRule) {
-        setBestFractionRule(MASTER_RULE_INDEX, rule, TRUE);
+    else if (baseValue == NFRule::kDefaultRule) {
+        setBestFractionRule(DEFAULT_RULE_INDEX, rule, TRUE);
     }
     else if (baseValue == NFRule::kInfinityRule) {
         delete nonNumericalRules[INFINITY_RULE_INDEX];
@@ -323,7 +323,7 @@
     for (int i = 0; i < NON_NUMERICAL_RULE_LENGTH; i++) {
         if (i != IMPROPER_FRACTION_RULE_INDEX
             && i != PROPER_FRACTION_RULE_INDEX
-            && i != MASTER_RULE_INDEX)
+            && i != DEFAULT_RULE_INDEX)
         {
             delete nonNumericalRules[i];
         }
@@ -375,7 +375,7 @@
         rules[i]->setDecimalFormatSymbols(newSymbols, status);
     }
     // Switch the fraction rules to mirror the DecimalFormatSymbols.
-    for (int32_t nonNumericalIdx = IMPROPER_FRACTION_RULE_INDEX; nonNumericalIdx <= MASTER_RULE_INDEX; nonNumericalIdx++) {
+    for (int32_t nonNumericalIdx = IMPROPER_FRACTION_RULE_INDEX; nonNumericalIdx <= DEFAULT_RULE_INDEX; nonNumericalIdx++) {
         if (nonNumericalRules[nonNumericalIdx]) {
             for (uint32_t fIdx = 0; fIdx < fractionRules.size(); fIdx++) {
                 NFRule *fractionRule = fractionRules[fIdx];
@@ -472,9 +472,9 @@
         }
     }
 
-    // if there's a master rule, use it to format the number
-    if (nonNumericalRules[MASTER_RULE_INDEX]) {
-        return nonNumericalRules[MASTER_RULE_INDEX];
+    // if there's a default rule, use it to format the number
+    if (nonNumericalRules[DEFAULT_RULE_INDEX]) {
+        return nonNumericalRules[DEFAULT_RULE_INDEX];
     }
 
     // and if we haven't yet returned a rule, use findNormalRule()
@@ -507,13 +507,13 @@
     // do them in findRule(), because the version of format() that
     // takes a long bypasses findRule() and goes straight to this
     // function.  This function does skip the fraction rules since
-    // we know the value is an integer (it also skips the master
+    // we know the value is an integer (it also skips the default
     // rule, since it's considered a fraction rule.  Skipping the
-    // master rule in this function is also how we avoid infinite
+    // default rule in this function is also how we avoid infinite
     // recursion)
 
     // {dlf} unfortunately this fails if there are no rules except
-    // special rules.  If there are no rules, use the master rule.
+    // special rules.  If there are no rules, use the default rule.
 
     // binary-search the rule list for the applicable rule
     // (a rule is used for all values from its base value to
@@ -553,8 +553,8 @@
         }
         return result;
     }
-    // else use the master rule
-    return nonNumericalRules[MASTER_RULE_INDEX];
+    // else use the default rule
+    return nonNumericalRules[DEFAULT_RULE_INDEX];
 }
 
 /**
@@ -792,7 +792,7 @@
         if (nonNumericalRules[i]) {
             if (rule->getBaseValue() == NFRule::kImproperFractionRule
                 || rule->getBaseValue() == NFRule::kProperFractionRule
-                || rule->getBaseValue() == NFRule::kMasterRule)
+                || rule->getBaseValue() == NFRule::kDefaultRule)
             {
                 for (uint32_t fIdx = 0; fIdx < fractionRules.size(); fIdx++) {
                     NFRule *fractionRule = fractionRules[fIdx];
diff --git a/icu4c/source/i18n/nfrule.cpp b/icu4c/source/i18n/nfrule.cpp
index bafa044..a9b84ed 100644
--- a/icu4c/source/i18n/nfrule.cpp
+++ b/icu4c/source/i18n/nfrule.cpp
@@ -153,7 +153,7 @@
         if ((rule1->baseValue > 0
             && (rule1->baseValue % util64_pow(rule1->radix, rule1->exponent)) == 0)
             || rule1->getType() == kImproperFractionRule
-            || rule1->getType() == kMasterRule) {
+            || rule1->getType() == kDefaultRule) {
 
             // if it passes that test, new up the second rule.  If the
             // rule set both rules will belong to is a fraction rule
@@ -181,9 +181,9 @@
             }
 
             // if the description began with "x.0" and contains bracketed
-            // text, it describes both the primary rule and the
+            // text, it describes both the default rule and the
             // improper fraction rule
-            else if (rule1->getType() == kMasterRule) {
+            else if (rule1->getType() == kDefaultRule) {
                 rule2->baseValue = rule1->baseValue;
                 rule1->setType(kImproperFractionRule);
             }
@@ -376,7 +376,7 @@
                 decimalPoint = descriptor.charAt(1);
             }
             else if (firstChar == gX && lastChar == gZero) {
-                setBaseValue(kMasterRule, status);
+                setBaseValue(kDefaultRule, status);
                 decimalPoint = descriptor.charAt(1);
             }
             else if (descriptor.compare(gNaN, 3) == 0) {
@@ -663,7 +663,7 @@
     case kNegativeNumberRule: result.append(gMinusX, 2); break;
     case kImproperFractionRule: result.append(gX).append(decimalPoint == 0 ? gDot : decimalPoint).append(gX); break;
     case kProperFractionRule: result.append(gZero).append(decimalPoint == 0 ? gDot : decimalPoint).append(gX); break;
-    case kMasterRule: result.append(gX).append(decimalPoint == 0 ? gDot : decimalPoint).append(gZero); break;
+    case kDefaultRule: result.append(gX).append(decimalPoint == 0 ? gDot : decimalPoint).append(gZero); break;
     case kInfinityRule: result.append(gInf, 3); break;
     case kNaNRule: result.append(gNaN, 3); break;
     default:
diff --git a/icu4c/source/i18n/nfrule.h b/icu4c/source/i18n/nfrule.h
index ed33eaa..989fbaa 100644
--- a/icu4c/source/i18n/nfrule.h
+++ b/icu4c/source/i18n/nfrule.h
@@ -38,7 +38,7 @@
         kNegativeNumberRule = -1,
         kImproperFractionRule = -2,
         kProperFractionRule = -3,
-        kMasterRule = -4,
+        kDefaultRule = -4,
         kInfinityRule = -5,
         kNaNRule = -6,
         kOtherRule = -7
diff --git a/icu4c/source/i18n/nfsubs.cpp b/icu4c/source/i18n/nfsubs.cpp
index 208543d..e3d1fc1 100644
--- a/icu4c/source/i18n/nfsubs.cpp
+++ b/icu4c/source/i18n/nfsubs.cpp
@@ -342,7 +342,7 @@
         // IntegralPartSubstitution
         else if (rule->getBaseValue() == NFRule::kImproperFractionRule
             || rule->getBaseValue() == NFRule::kProperFractionRule
-            || rule->getBaseValue() == NFRule::kMasterRule) {
+            || rule->getBaseValue() == NFRule::kDefaultRule) {
             return new IntegralPartSubstitution(pos, ruleSet, description, status);
         }
 
@@ -371,7 +371,7 @@
         // FractionalPartSubstitution
         else if (rule->getBaseValue() == NFRule::kImproperFractionRule
             || rule->getBaseValue() == NFRule::kProperFractionRule
-            || rule->getBaseValue() == NFRule::kMasterRule) {
+            || rule->getBaseValue() == NFRule::kDefaultRule) {
             return new FractionalPartSubstitution(pos, ruleSet, description, status);
         }
 
diff --git a/icu4c/source/test/testdata/localeMatcherTest.txt b/icu4c/source/test/testdata/localeMatcherTest.txt
index 7a10986..70afcd0 100644
--- a/icu4c/source/test/testdata/localeMatcherTest.txt
+++ b/icu4c/source/test/testdata/localeMatcherTest.txt
@@ -279,7 +279,7 @@
 zh-Hant >> und-TW
 zh >> und-TW
 
-** test: testMatchGrandfatheredCode
+** test: testMatchLegacyCode
 
 @supported=fr, i-klingon, en-Latn-US
 en-GB-oed >> en-Latn-US
@@ -984,7 +984,7 @@
 x-piglatin >> x-bork
 x-bork >> x-bork
 
-** test: MatchGrandfatheredCode
+** test: MatchLegacyCode
 @supported=fr, i-klingon, en-Latn-US
 en-GB-oed >> en-Latn-US
 i-klingon >> tlh
@@ -1525,7 +1525,7 @@
 x-piglatin >> fr
 x-bork >> x-bork
 
-** test: grandfathered codes
+** test: legacy codes
 @supported=fr, i-klingon, en-Latn-US
 en-GB-oed >> en-Latn-US
 i-klingon >> tlh
diff --git a/icu4c/source/test/testdata/rbbitst.txt b/icu4c/source/test/testdata/rbbitst.txt
index 98cf688..b9a0611 100644
--- a/icu4c/source/test/testdata/rbbitst.txt
+++ b/icu4c/source/test/testdata/rbbitst.txt
@@ -32,7 +32,7 @@
 #   [ICU4C]   source/test/testdata/rbbitst.txt
 #   [ICU4J]   main/tests/core/src/com/ibm/icu/dev/test/rbbi/rbbitst.txt
 #
-# ICU4C's copy is the master.  If any changes are made to ICU4J's copy, make sure they
+# ICU4C's copy is the primary.  If any changes are made to ICU4J's copy, make sure they
 #  are merged back into ICU4C's copy of the file, lest they get overwritten later.
 # TODO:  figure out how to have a single copy of the file for use by both C and Java.
 
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/locale/LanguageTag.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/locale/LanguageTag.java
index c5cf38e..3adf08a 100644
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/locale/LanguageTag.java
+++ b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/locale/LanguageTag.java
@@ -38,13 +38,13 @@
     private List<String> _variants = Collections.emptyList();   // variant subtags
     private List<String> _extensions = Collections.emptyList(); // extensions
 
-    // Map contains grandfathered tags and its preferred mappings from
-    // http://www.ietf.org/rfc/rfc5646.txt
-    private static final Map<AsciiUtil.CaseInsensitiveKey, String[]> GRANDFATHERED =
+    // The Map contains legacy language tags (marked as “Type: grandfathered” in BCP 47)
+    // and their preferred mappings from BCP 47.
+    private static final Map<AsciiUtil.CaseInsensitiveKey, String[]> LEGACY =
         new HashMap<AsciiUtil.CaseInsensitiveKey, String[]>();
 
     static {
-        // grandfathered = irregular           ; non-redundant tags registered
+        // legacy        = irregular           ; non-redundant tags registered
         //               / regular             ; during the RFC 3066 era
         //
         // irregular     = "en-GB-oed"         ; irregular tags do not match
@@ -105,57 +105,17 @@
             {"zh-xiang",    "hsn"},
         };
         for (String[] e : entries) {
-            GRANDFATHERED.put(new AsciiUtil.CaseInsensitiveKey(e[0]), e);
+            LEGACY.put(new AsciiUtil.CaseInsensitiveKey(e[0]), e);
         }
     }
 
     private LanguageTag() {
     }
 
-    /*
-     * BNF in RFC5464
-     *  
-     * Language-Tag  = langtag             ; normal language tags
-     *               / privateuse          ; private use tag
-     *               / grandfathered       ; grandfathered tags
-     *
-     * 
-     * langtag       = language
-     *                 ["-" script]
-     *                 ["-" region]
-     *                 *("-" variant)
-     *                 *("-" extension)
-     *                 ["-" privateuse]
-     * 
-     * language      = 2*3ALPHA            ; shortest ISO 639 code
-     *                 ["-" extlang]       ; sometimes followed by
-     *                                     ; extended language subtags
-     *               / 4ALPHA              ; or reserved for future use
-     *               / 5*8ALPHA            ; or registered language subtag
-     * 
-     * extlang       = 3ALPHA              ; selected ISO 639 codes
-     *                 *2("-" 3ALPHA)      ; permanently reserved
-     * 
-     * script        = 4ALPHA              ; ISO 15924 code
-     * 
-     * region        = 2ALPHA              ; ISO 3166-1 code
-     *               / 3DIGIT              ; UN M.49 code
-     * 
-     * variant       = 5*8alphanum         ; registered variants
-     *               / (DIGIT 3alphanum)
-     * 
-     * extension     = singleton 1*("-" (2*8alphanum))
-     * 
-     *                                     ; Single alphanumerics
-     *                                     ; "x" reserved for private use
-     * singleton     = DIGIT               ; 0 - 9
-     *               / %x41-57             ; A - W
-     *               / %x59-5A             ; Y - Z
-     *               / %x61-77             ; a - w
-     *               / %x79-7A             ; y - z
-     * 
-     * privateuse    = "x" 1*("-" (1*8alphanum))
-     * 
+    /**
+     * See BCP 47 “Tags for Identifying Languages”:
+     * https://www.rfc-editor.org/info/bcp47 -->
+     * https://www.rfc-editor.org/rfc/rfc5646.html#section-2.1
      */
     public static LanguageTag parse(String languageTag, ParseStatus sts) {
         if (sts == null) {
@@ -166,8 +126,7 @@
 
         StringTokenIterator itr;
 
-        // Check if the tag is grandfathered
-        String[] gfmap = GRANDFATHERED.get(new AsciiUtil.CaseInsensitiveKey(languageTag));
+        String[] gfmap = LEGACY.get(new AsciiUtil.CaseInsensitiveKey(languageTag));
         if (gfmap != null) {
             // use preferred mapping
             itr = new StringTokenIterator(gfmap[1], SEP);
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/util/ULocale.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/util/ULocale.java
index 5081767..b811d50 100644
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/util/ULocale.java
+++ b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/util/ULocale.java
@@ -70,7 +70,8 @@
  * Canonicalization additionally performs the following:
  * <ul>
  * <li>POSIX ids are converted to ICU format IDs</li>
- * <li>'grandfathered' 3066 ids are converted to ICU standard form</li>
+ * <li>Legacy language tags (marked as “Type: grandfathered” in BCP 47)
+ * are converted to ICU standard form</li>
  * <li>'PREEURO' and 'EURO' variants are converted to currency keyword form,
  * with the currency
  * id appropriate to the country of the locale (for PREEURO) or EUR (for EURO).
@@ -1033,7 +1034,7 @@
 
     /**
      * {@icu} Returns the canonical name for the specified locale ID.  This is used to
-     * convert POSIX and other grandfathered IDs to standard ICU form.
+     * convert POSIX and other legacy IDs to standard ICU form.
      * @param localeID the locale id
      * @return the canonicalized id
      * @stable ICU 3.0
@@ -2666,60 +2667,18 @@
      * script to title case, country to upper case, variant to upper case,
      * and extensions to lower case.
      *
-     * <p>This implements the 'Language-Tag' production of BCP47, and
-     * so supports grandfathered (regular and irregular) as well as
-     * private use language tags.  Stand alone private use tags are
-     * represented as empty language and extension 'x-whatever',
-     * and grandfathered tags are converted to their canonical replacements
-     * where they exist.  
+     * <p>This implements the 'Language-Tag' production of BCP 47, and so
+     * supports legacy language tags (marked as “Type: grandfathered” in BCP 47)
+     * (regular and irregular) as well as private use language tags.
      *
-     * <p>Grandfathered tags with canonical replacements are as follows:
+     * <p>Stand-alone private use tags are represented as empty language and extension 'x-whatever',
+     * and legacy tags are converted to their canonical replacements where they exist.
      *
-     * <table>
-     * <tbody align="center">
-     * <tr><th>grandfathered tag</th><th>&nbsp;</th><th>modern replacement</th></tr>
-     * <tr><td>art-lojban</td><td>&nbsp;</td><td>jbo</td></tr>
-     * <tr><td>i-ami</td><td>&nbsp;</td><td>ami</td></tr>
-     * <tr><td>i-bnn</td><td>&nbsp;</td><td>bnn</td></tr>
-     * <tr><td>i-hak</td><td>&nbsp;</td><td>hak</td></tr>
-     * <tr><td>i-klingon</td><td>&nbsp;</td><td>tlh</td></tr>
-     * <tr><td>i-lux</td><td>&nbsp;</td><td>lb</td></tr>
-     * <tr><td>i-navajo</td><td>&nbsp;</td><td>nv</td></tr>
-     * <tr><td>i-pwn</td><td>&nbsp;</td><td>pwn</td></tr>
-     * <tr><td>i-tao</td><td>&nbsp;</td><td>tao</td></tr>
-     * <tr><td>i-tay</td><td>&nbsp;</td><td>tay</td></tr>
-     * <tr><td>i-tsu</td><td>&nbsp;</td><td>tsu</td></tr>
-     * <tr><td>no-bok</td><td>&nbsp;</td><td>nb</td></tr>
-     * <tr><td>no-nyn</td><td>&nbsp;</td><td>nn</td></tr>
-     * <tr><td>sgn-BE-FR</td><td>&nbsp;</td><td>sfb</td></tr>
-     * <tr><td>sgn-BE-NL</td><td>&nbsp;</td><td>vgt</td></tr>
-     * <tr><td>sgn-CH-DE</td><td>&nbsp;</td><td>sgg</td></tr>
-     * <tr><td>zh-guoyu</td><td>&nbsp;</td><td>cmn</td></tr>
-     * <tr><td>zh-hakka</td><td>&nbsp;</td><td>hak</td></tr>
-     * <tr><td>zh-min-nan</td><td>&nbsp;</td><td>nan</td></tr>
-     * <tr><td>zh-xiang</td><td>&nbsp;</td><td>hsn</td></tr>
-     * </tbody>
-     * </table>
+     * <p>Note that a few legacy tags have no modern replacement;
+     * these will be converted using the fallback described in
+     * the first paragraph, so some information might be lost.
      *
-     * <p>Grandfathered tags with no modern replacement will be
-     * converted as follows:
-     *
-     * <table>
-     * <tbody align="center">
-     * <tr><th>grandfathered tag</th><th>&nbsp;</th><th>converts to</th></tr>
-     * <tr><td>cel-gaulish</td><td>&nbsp;</td><td>xtg-x-cel-gaulish</td></tr>
-     * <tr><td>en-GB-oed</td><td>&nbsp;</td><td>en-GB-x-oed</td></tr>
-     * <tr><td>i-default</td><td>&nbsp;</td><td>en-x-i-default</td></tr>
-     * <tr><td>i-enochian</td><td>&nbsp;</td><td>und-x-i-enochian</td></tr>
-     * <tr><td>i-mingo</td><td>&nbsp;</td><td>see-x-i-mingo</td></tr>
-     * <tr><td>zh-min</td><td>&nbsp;</td><td>nan-x-zh-min</td></tr>
-     * </tbody>
-     * </table>
-     *
-     * <p>For a list of all grandfathered tags, see the
-     * IANA Language Subtag Registry (search for "Type: grandfathered").
-     *
-     * <p><b>Note</b>: there is no guarantee that <code>toLanguageTag</code>
+     * <p><b>Note</b>: There is no guarantee that <code>toLanguageTag</code>
      * and <code>forLanguageTag</code> will round-trip.
      *
      * @param languageTag the language tag
@@ -2821,7 +2780,7 @@
          * Resets the Builder to match the provided IETF BCP 47
          * language tag.  Discards the existing state.  Null and the
          * empty string cause the builder to be reset, like {@link
-         * #clear}.  Grandfathered tags (see {@link
+         * #clear}.  Legacy tags (see {@link
          * ULocale#forLanguageTag}) are converted to their canonical
          * form before being processed.  Otherwise, the language tag
          * must be well-formed (see {@link ULocale}) or an exception is
diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/CalendarUtil.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/CalendarUtil.java
index 83da8ce..8ceb8d1 100644
--- a/icu4j/main/classes/core/src/com/ibm/icu/impl/CalendarUtil.java
+++ b/icu4j/main/classes/core/src/com/ibm/icu/impl/CalendarUtil.java
@@ -46,7 +46,7 @@
             return calType.toLowerCase(Locale.ROOT);
         }
 
-        // Canonicalize, so grandfathered variant will be transformed to keywords
+        // Canonicalize, so that an old-style variant will be transformed to keywords.
         ULocale canonical = ULocale.createCanonical(loc.toString());
         calType = canonical.getKeywordValue(CALKEY);
         if (calType != null) {
diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/locale/LanguageTag.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/locale/LanguageTag.java
index 14d1a94..53f9879 100644
--- a/icu4j/main/classes/core/src/com/ibm/icu/impl/locale/LanguageTag.java
+++ b/icu4j/main/classes/core/src/com/ibm/icu/impl/locale/LanguageTag.java
@@ -38,13 +38,13 @@
     private List<String> _variants = Collections.emptyList();   // variant subtags
     private List<String> _extensions = Collections.emptyList(); // extensions
 
-    // Map contains grandfathered tags and its preferred mappings from
-    // http://www.ietf.org/rfc/rfc5646.txt
-    private static final Map<AsciiUtil.CaseInsensitiveKey, String[]> GRANDFATHERED =
+    // The Map contains legacy language tags (marked as “Type: grandfathered” in BCP 47)
+    // and their preferred mappings from BCP 47.
+    private static final Map<AsciiUtil.CaseInsensitiveKey, String[]> LEGACY =
         new HashMap<AsciiUtil.CaseInsensitiveKey, String[]>();
 
     static {
-        // grandfathered = irregular           ; non-redundant tags registered
+        // legacy        = irregular           ; non-redundant tags registered
         //               / regular             ; during the RFC 3066 era
         //
         // irregular     = "en-GB-oed"         ; irregular tags do not match
@@ -105,57 +105,17 @@
             {"zh-xiang",    "hsn"},
         };
         for (String[] e : entries) {
-            GRANDFATHERED.put(new AsciiUtil.CaseInsensitiveKey(e[0]), e);
+            LEGACY.put(new AsciiUtil.CaseInsensitiveKey(e[0]), e);
         }
     }
 
     private LanguageTag() {
     }
 
-    /*
-     * BNF in RFC5464
-     *
-     * Language-Tag  = langtag             ; normal language tags
-     *               / privateuse          ; private use tag
-     *               / grandfathered       ; grandfathered tags
-     *
-     *
-     * langtag       = language
-     *                 ["-" script]
-     *                 ["-" region]
-     *                 *("-" variant)
-     *                 *("-" extension)
-     *                 ["-" privateuse]
-     *
-     * language      = 2*3ALPHA            ; shortest ISO 639 code
-     *                 ["-" extlang]       ; sometimes followed by
-     *                                     ; extended language subtags
-     *               / 4ALPHA              ; or reserved for future use
-     *               / 5*8ALPHA            ; or registered language subtag
-     *
-     * extlang       = 3ALPHA              ; selected ISO 639 codes
-     *                 *2("-" 3ALPHA)      ; permanently reserved
-     *
-     * script        = 4ALPHA              ; ISO 15924 code
-     *
-     * region        = 2ALPHA              ; ISO 3166-1 code
-     *               / 3DIGIT              ; UN M.49 code
-     *
-     * variant       = 5*8alphanum         ; registered variants
-     *               / (DIGIT 3alphanum)
-     *
-     * extension     = singleton 1*("-" (2*8alphanum))
-     *
-     *                                     ; Single alphanumerics
-     *                                     ; "x" reserved for private use
-     * singleton     = DIGIT               ; 0 - 9
-     *               / %x41-57             ; A - W
-     *               / %x59-5A             ; Y - Z
-     *               / %x61-77             ; a - w
-     *               / %x79-7A             ; y - z
-     *
-     * privateuse    = "x" 1*("-" (1*8alphanum))
-     *
+    /**
+     * See BCP 47 “Tags for Identifying Languages”:
+     * https://www.rfc-editor.org/info/bcp47 -->
+     * https://www.rfc-editor.org/rfc/rfc5646.html#section-2.1
      */
     public static LanguageTag parse(String languageTag, ParseStatus sts) {
         if (sts == null) {
@@ -165,14 +125,13 @@
         }
 
         StringTokenIterator itr;
-        boolean isGrandfathered = false;
+        boolean isLegacy = false;
 
-        // Check if the tag is grandfathered
-        String[] gfmap = GRANDFATHERED.get(new AsciiUtil.CaseInsensitiveKey(languageTag));
+        String[] gfmap = LEGACY.get(new AsciiUtil.CaseInsensitiveKey(languageTag));
         // Language tag is at least 2 alpha so we can skip searching the first 2 chars.
         int dash = 2;
         while (gfmap == null && (dash = languageTag.indexOf('-', dash + 1)) != -1) {
-            gfmap = GRANDFATHERED.get(new AsciiUtil.CaseInsensitiveKey(languageTag.substring(0, dash)));
+            gfmap = LEGACY.get(new AsciiUtil.CaseInsensitiveKey(languageTag.substring(0, dash)));
         }
 
         if (gfmap != null) {
@@ -183,7 +142,7 @@
                 // append the rest of the tag.
                 itr = new StringTokenIterator(gfmap[1] + languageTag.substring(dash), SEP);
             }
-            isGrandfathered = true;
+            isLegacy = true;
         } else {
             itr = new StringTokenIterator(languageTag, SEP);
         }
@@ -202,8 +161,8 @@
         }
         tag.parsePrivateuse(itr, sts);
 
-        if (isGrandfathered) {
-            // Grandfathered tag is replaced with a well-formed tag above.
+        if (isLegacy) {
+            // A legacy tag is replaced with a well-formed tag above.
             // However, the parsed length must be the original tag length.
             assert (itr.isDone());
             assert (!sts.isError());
diff --git a/icu4j/main/classes/core/src/com/ibm/icu/text/DateIntervalFormat.java b/icu4j/main/classes/core/src/com/ibm/icu/text/DateIntervalFormat.java
index 62bccc4..3ba5517 100644
--- a/icu4j/main/classes/core/src/com/ibm/icu/text/DateIntervalFormat.java
+++ b/icu4j/main/classes/core/src/com/ibm/icu/text/DateIntervalFormat.java
@@ -1234,7 +1234,7 @@
         if (fDateFormat != null) {
             fDateFormat.setTimeZone(zoneToSet);
         }
-        // fDateFormat has the master calendar for the DateIntervalFormat;
+        // fDateFormat has the primary calendar for the DateIntervalFormat;
         // fFromCalendar and fToCalendar are internal work clones of that calendar.
         if (fFromCalendar != null) {
             fFromCalendar.setTimeZone(zoneToSet);
diff --git a/icu4j/main/classes/core/src/com/ibm/icu/text/NFRule.java b/icu4j/main/classes/core/src/com/ibm/icu/text/NFRule.java
index 4a0c4a8..75ac157 100644
--- a/icu4j/main/classes/core/src/com/ibm/icu/text/NFRule.java
+++ b/icu4j/main/classes/core/src/com/ibm/icu/text/NFRule.java
@@ -41,9 +41,9 @@
     static final int PROPER_FRACTION_RULE = -3;
 
     /**
-     * Special base value used to identify a master rule
+     * Special base value used to identify a default rule
      */
-    static final int MASTER_RULE = -4;
+    static final int DEFAULT_RULE = -4;
 
     /**
      * Special base value used to identify an infinity rule
@@ -169,7 +169,7 @@
             if ((rule1.baseValue > 0
                  && rule1.baseValue % (power(rule1.radix, rule1.exponent)) == 0)
                 || rule1.baseValue == IMPROPER_FRACTION_RULE
-                || rule1.baseValue == MASTER_RULE)
+                || rule1.baseValue == DEFAULT_RULE)
             {
 
                 // if it passes that test, new up the second rule.  If the
@@ -190,9 +190,9 @@
                     // the proper fraction rule
                     rule2.baseValue = PROPER_FRACTION_RULE;
                 }
-                else if (rule1.baseValue == MASTER_RULE) {
+                else if (rule1.baseValue == DEFAULT_RULE) {
                     // if the description began with "x.0" and contains bracketed
-                    // text, it describes both the master rule and the
+                    // text, it describes both the default rule and the
                     // improper fraction rule
                     rule2.baseValue = rule1.baseValue;
                     rule1.baseValue = IMPROPER_FRACTION_RULE;
@@ -378,7 +378,7 @@
                     decimalPoint = descriptor.charAt(1);
                 }
                 else if (firstChar == 'x' && lastChar == '0') {
-                    setBaseValue(MASTER_RULE);
+                    setBaseValue(DEFAULT_RULE);
                     decimalPoint = descriptor.charAt(1);
                 }
                 else if (descriptor.equals("NaN")) {
@@ -651,7 +651,7 @@
         else if (baseValue == PROPER_FRACTION_RULE) {
             result.append('0').append(decimalPoint == 0 ? '.' : decimalPoint).append("x: ");
         }
-        else if (baseValue == MASTER_RULE) {
+        else if (baseValue == DEFAULT_RULE) {
             result.append('x').append(decimalPoint == 0 ? '.' : decimalPoint).append("0: ");
         }
         else if (baseValue == INFINITY_RULE) {
@@ -1222,7 +1222,7 @@
      * Used by stripPrefix() to match characters.  If lenient parse mode
      * is off, this just calls startsWith().  If lenient parse mode is on,
      * this function uses CollationElementIterators to match characters in
-     * the strings (only primary-order differences are significant in
+     * the strings (primary-order differences are significant in
      * determining whether there's a match).
      * @param str The string being tested
      * @param prefix The text we're hoping to see at the beginning
diff --git a/icu4j/main/classes/core/src/com/ibm/icu/text/NFRuleSet.java b/icu4j/main/classes/core/src/com/ibm/icu/text/NFRuleSet.java
index 2a70ec5..978d748 100644
--- a/icu4j/main/classes/core/src/com/ibm/icu/text/NFRuleSet.java
+++ b/icu4j/main/classes/core/src/com/ibm/icu/text/NFRuleSet.java
@@ -57,7 +57,7 @@
     /** 0.x */
     static final int PROPER_FRACTION_RULE_INDEX = 2;
     /** x.0 */
-    static final int MASTER_RULE_INDEX = 3;
+    static final int DEFAULT_RULE_INDEX = 3;
     /** Inf */
     static final int INFINITY_RULE_INDEX = 4;
     /** NaN */
@@ -243,8 +243,8 @@
         else if (baseValue == NFRule.PROPER_FRACTION_RULE) {
             setBestFractionRule(NFRuleSet.PROPER_FRACTION_RULE_INDEX, rule, true);
         }
-        else if (baseValue == NFRule.MASTER_RULE) {
-            setBestFractionRule(NFRuleSet.MASTER_RULE_INDEX, rule, true);
+        else if (baseValue == NFRule.DEFAULT_RULE) {
+            setBestFractionRule(NFRuleSet.DEFAULT_RULE_INDEX, rule, true);
         }
         else if (baseValue == NFRule.INFINITY_RULE) {
             nonNumericalRules[NFRuleSet.INFINITY_RULE_INDEX] = rule;
@@ -368,7 +368,7 @@
             if (rule != null) {
                 if (rule.getBaseValue() == NFRule.IMPROPER_FRACTION_RULE
                     || rule.getBaseValue() == NFRule.PROPER_FRACTION_RULE
-                    || rule.getBaseValue() == NFRule.MASTER_RULE)
+                    || rule.getBaseValue() == NFRule.DEFAULT_RULE)
                 {
                     for (NFRule fractionRule : fractionRules) {
                         if (fractionRule.getBaseValue() == rule.getBaseValue()) {
@@ -508,9 +508,9 @@
             }
         }
 
-        // if there's a master rule, use it to format the number
-        if (nonNumericalRules[MASTER_RULE_INDEX] != null) {
-            return nonNumericalRules[MASTER_RULE_INDEX];
+        // if there's a default rule, use it to format the number
+        if (nonNumericalRules[DEFAULT_RULE_INDEX] != null) {
+            return nonNumericalRules[DEFAULT_RULE_INDEX];
         }
         else {
             // and if we haven't yet returned a rule, use findNormalRule()
@@ -557,9 +557,9 @@
         // do them in findRule(), because the version of format() that
         // takes a long bypasses findRule() and goes straight to this
         // function.  This function does skip the fraction rules since
-        // we know the value is an integer (it also skips the master
+        // we know the value is an integer (it also skips the default
         // rule, since it's considered a fraction rule.  Skipping the
-        // master rule in this function is also how we avoid infinite
+        // default rule in this function is also how we avoid infinite
         // recursion)
 
         // binary-search the rule list for the applicable rule
@@ -600,8 +600,8 @@
             }
             return result;
         }
-        // else use the master rule
-        return nonNumericalRules[MASTER_RULE_INDEX];
+        // else use the default rule
+        return nonNumericalRules[DEFAULT_RULE_INDEX];
     }
 
     /**
@@ -829,7 +829,8 @@
         }
         // Switch the fraction rules to mirror the DecimalFormatSymbols.
         if (fractionRules != null) {
-            for (int nonNumericalIdx = IMPROPER_FRACTION_RULE_INDEX; nonNumericalIdx <= MASTER_RULE_INDEX; nonNumericalIdx++) {
+            for (int nonNumericalIdx = IMPROPER_FRACTION_RULE_INDEX;
+                 nonNumericalIdx <= DEFAULT_RULE_INDEX; nonNumericalIdx++) {
                 if (nonNumericalRules[nonNumericalIdx] != null) {
                     for (NFRule rule : fractionRules) {
                         if (nonNumericalRules[nonNumericalIdx].getBaseValue() == rule.getBaseValue()) {
diff --git a/icu4j/main/classes/core/src/com/ibm/icu/text/NFSubstitution.java b/icu4j/main/classes/core/src/com/ibm/icu/text/NFSubstitution.java
index e2a992b..65db0c2 100644
--- a/icu4j/main/classes/core/src/com/ibm/icu/text/NFSubstitution.java
+++ b/icu4j/main/classes/core/src/com/ibm/icu/text/NFSubstitution.java
@@ -90,7 +90,7 @@
             }
             else if (rule.getBaseValue() == NFRule.IMPROPER_FRACTION_RULE
                      || rule.getBaseValue() == NFRule.PROPER_FRACTION_RULE
-                     || rule.getBaseValue() == NFRule.MASTER_RULE)
+                     || rule.getBaseValue() == NFRule.DEFAULT_RULE)
             {
                 // if the rule is a fraction rule, return an IntegralPartSubstitution
                 return new IntegralPartSubstitution(pos, ruleSet, description);
@@ -115,7 +115,7 @@
             }
             else if (rule.getBaseValue() == NFRule.IMPROPER_FRACTION_RULE
                      || rule.getBaseValue() == NFRule.PROPER_FRACTION_RULE
-                     || rule.getBaseValue() == NFRule.MASTER_RULE)
+                     || rule.getBaseValue() == NFRule.DEFAULT_RULE)
             {
                 // if the rule is a fraction rule, return a
                 // FractionalPartSubstitution
diff --git a/icu4j/main/classes/core/src/com/ibm/icu/text/RuleBasedNumberFormat.java b/icu4j/main/classes/core/src/com/ibm/icu/text/RuleBasedNumberFormat.java
index dbab314..0e69dac 100644
--- a/icu4j/main/classes/core/src/com/ibm/icu/text/RuleBasedNumberFormat.java
+++ b/icu4j/main/classes/core/src/com/ibm/icu/text/RuleBasedNumberFormat.java
@@ -275,7 +275,7 @@
  *   <tr>
  *     <td style="width: 5%; vertical-align: top;"></td>
  *     <td style="width: 8%; vertical-align: top;">x.0:</td>
- *     <td valign="top">The rule is a <em>master rule</em>. If the full stop in
+ *     <td valign="top">The rule is a <em>default rule</em>. If the full stop in
  *     the middle of the rule name is replaced with the decimal point
  *     that is used in the language or DecimalFormatSymbols, then that rule will
  *     have precedence when formatting and parsing this rule. For example, some
@@ -313,9 +313,9 @@
  * algorithms: If the rule set is a regular rule set, do the following:
  *
  * <ul>
- *   <li>If the rule set includes a master rule (and the number was passed in as a <tt>double</tt>),
- *     use the master rule.&nbsp; (If the number being formatted was passed in as a <tt>long</tt>,
- *     the master rule is ignored.)</li>
+ *   <li>If the rule set includes a default rule (and the number was passed in as a <tt>double</tt>),
+ *     use the default rule.&nbsp; (If the number being formatted was passed in as a <tt>long</tt>,
+ *     the default rule is ignored.)</li>
  *   <li>If the number is negative, use the negative-number rule.</li>
  *   <li>If the number has a fractional part and is greater than 1, use the improper fraction
  *     rule.</li>
@@ -377,7 +377,7 @@
  *   <tr>
  *     <td style="width: 37;"></td>
  *     <td style="width: 23;"></td>
- *     <td style="width: 165; vertical-align: top;">in fraction or master rule</td>
+ *     <td style="width: 165; vertical-align: top;">in fraction or default rule</td>
  *     <td>Isolate the number's fractional part and format it.</td>
  *   </tr>
  *   <tr>
@@ -415,7 +415,7 @@
  *   <tr>
  *     <td style="width: 37;"></td>
  *     <td style="width: 23;"></td>
- *     <td style="width: 165; vertical-align: top;">in fraction or master rule</td>
+ *     <td style="width: 165; vertical-align: top;">in fraction or default rule</td>
  *     <td>Isolate the number's integral part and format it.</td>
  *   </tr>
  *   <tr>
@@ -452,7 +452,7 @@
  *   <tr>
  *     <td style="width: 37;"></td>
  *     <td style="width: 23;"></td>
- *     <td style="width: 165; vertical-align: top;">in master rule</td>
+ *     <td style="width: 165; vertical-align: top;">in default rule</td>
  *     <td>Omit the optional text if the number is an integer (same as specifying both an x.x
  *     rule and an x.0 rule)</td>
  *   </tr>
@@ -1153,7 +1153,7 @@
 
     /**
      * Formats the specified number according to the specified rule set.
-     * (If the specified rule set specifies a master ["x.0"] rule, this function
+     * (If the specified rule set specifies a default ["x.0"] rule, this function
      * ignores it.  Convert the number to a double first if you ned it.)  This
      * function preserves all the precision in the long-- it doesn't convert it
      * to a double.
@@ -1199,7 +1199,7 @@
     /**
      * Formats the specified number using the formatter's default rule set.
      * (The default rule set is the last public rule set defined in the description.)
-     * (If the specified rule set specifies a master ["x.0"] rule, this function
+     * (If the specified rule set specifies a default ["x.0"] rule, this function
      * ignores it.  Convert the number to a double first if you ned it.)  This
      * function preserves all the precision in the long-- it doesn't convert it
      * to a double.
diff --git a/icu4j/main/classes/core/src/com/ibm/icu/util/Region.java b/icu4j/main/classes/core/src/com/ibm/icu/util/Region.java
index 2fabbb0..b158af3 100644
--- a/icu4j/main/classes/core/src/com/ibm/icu/util/Region.java
+++ b/icu4j/main/classes/core/src/com/ibm/icu/util/Region.java
@@ -215,7 +215,7 @@
 
         regions = new ArrayList<Region>(regionCodes.size());
 
-        // First process the region codes and create the master array of regions.
+        // First process the region codes and create the primary array of regions.
         for ( String id : regionCodes) {
             Region r = new Region();
             r.id = id;
@@ -244,7 +244,7 @@
                 Region r;
                 if ( regionIDMap.containsKey(aliasFrom) ) {  // This is a deprecated region
                     r = regionIDMap.get(aliasFrom);
-                } else { // Deprecated region code not in the master codes list - so need to create a deprecated region for it.
+                } else { // Deprecated region code not in the primary codes list - so need to create a deprecated region for it.
                     r = new Region();
                     r.id = aliasFrom;
                     regionIDMap.put(aliasFrom, r);
diff --git a/icu4j/main/classes/core/src/com/ibm/icu/util/ULocale.java b/icu4j/main/classes/core/src/com/ibm/icu/util/ULocale.java
index ac8746f..8c3a4eb 100644
--- a/icu4j/main/classes/core/src/com/ibm/icu/util/ULocale.java
+++ b/icu4j/main/classes/core/src/com/ibm/icu/util/ULocale.java
@@ -80,7 +80,8 @@
  * Canonicalization additionally performs the following:
  * <ul>
  * <li>POSIX ids are converted to ICU format IDs</li>
- * <li>'grandfathered' 3066 ids are converted to ICU standard form</li>
+ * <li>Legacy language tags (marked as “Type: grandfathered” in BCP 47)
+ * are converted to ICU standard form</li>
  * </ul>
  * All ULocale constructors automatically normalize the locale id.  To handle
  * POSIX ids, <code>canonicalize</code> can be called to convert the id
@@ -1204,7 +1205,7 @@
 
     /**
      * {@icu} Returns the canonical name according to CLDR for the specified locale ID.
-     * This is used to convert POSIX and other grandfathered IDs to standard ICU form.
+     * This is used to convert POSIX and other legacy IDs to standard ICU form.
      * @param localeID the locale id
      * @return the canonicalized id
      * @stable ICU 3.0
@@ -1242,7 +1243,7 @@
         // element in Supplemental Data, replace the language subtag with the replacement value.
         // If there are additional subtags in the replacement value, add them to the result, but
         // only if there is no corresponding subtag already in the tag.
-        // Five special deprecated grandfathered codes (such as i-default) are in type attributes, and are also replaced.
+        // Five special deprecated codes (such as i-default) are in type attributes, and are also replaced.
         try {
             UResourceBundle languageAlias = UResourceBundle.getBundleInstance(ICUData.ICU_BASE_NAME,
                 "metadata", ICUResourceBundle.ICU_DATA_CLASS_LOADER)
@@ -3201,58 +3202,16 @@
      *
      * </ul>
      *
-     * <p>This implements the 'Language-Tag' production of BCP47, and
-     * so supports grandfathered (regular and irregular) as well as
-     * private use language tags.  Stand alone private use tags are
-     * represented as empty language and extension 'x-whatever',
-     * and grandfathered tags are converted to their canonical replacements
-     * where they exist.
+     * <p>This implements the 'Language-Tag' production of BCP 47, and so
+     * supports legacy language tags (marked as “Type: grandfathered” in BCP 47)
+     * (regular and irregular) as well as private use language tags.
      *
-     * <p>Grandfathered tags with canonical replacements are as follows:
+     * <p>Stand-alone private use tags are represented as empty language and extension 'x-whatever',
+     * and legacy tags are converted to their canonical replacements where they exist.
      *
-     * <table>
-     * <tbody align="center">
-     * <tr><th>grandfathered tag</th><th>&nbsp;</th><th>modern replacement</th></tr>
-     * <tr><td>art-lojban</td><td>&nbsp;</td><td>jbo</td></tr>
-     * <tr><td>i-ami</td><td>&nbsp;</td><td>ami</td></tr>
-     * <tr><td>i-bnn</td><td>&nbsp;</td><td>bnn</td></tr>
-     * <tr><td>i-hak</td><td>&nbsp;</td><td>hak</td></tr>
-     * <tr><td>i-klingon</td><td>&nbsp;</td><td>tlh</td></tr>
-     * <tr><td>i-lux</td><td>&nbsp;</td><td>lb</td></tr>
-     * <tr><td>i-navajo</td><td>&nbsp;</td><td>nv</td></tr>
-     * <tr><td>i-pwn</td><td>&nbsp;</td><td>pwn</td></tr>
-     * <tr><td>i-tao</td><td>&nbsp;</td><td>tao</td></tr>
-     * <tr><td>i-tay</td><td>&nbsp;</td><td>tay</td></tr>
-     * <tr><td>i-tsu</td><td>&nbsp;</td><td>tsu</td></tr>
-     * <tr><td>no-bok</td><td>&nbsp;</td><td>nb</td></tr>
-     * <tr><td>no-nyn</td><td>&nbsp;</td><td>nn</td></tr>
-     * <tr><td>sgn-BE-FR</td><td>&nbsp;</td><td>sfb</td></tr>
-     * <tr><td>sgn-BE-NL</td><td>&nbsp;</td><td>vgt</td></tr>
-     * <tr><td>sgn-CH-DE</td><td>&nbsp;</td><td>sgg</td></tr>
-     * <tr><td>zh-guoyu</td><td>&nbsp;</td><td>cmn</td></tr>
-     * <tr><td>zh-hakka</td><td>&nbsp;</td><td>hak</td></tr>
-     * <tr><td>zh-min-nan</td><td>&nbsp;</td><td>nan</td></tr>
-     * <tr><td>zh-xiang</td><td>&nbsp;</td><td>hsn</td></tr>
-     * </tbody>
-     * </table>
-     *
-     * <p>Grandfathered tags with no modern replacement will be
-     * converted as follows:
-     *
-     * <table>
-     * <tbody align="center">
-     * <tr><th>grandfathered tag</th><th>&nbsp;</th><th>converts to</th></tr>
-     * <tr><td>cel-gaulish</td><td>&nbsp;</td><td>xtg-x-cel-gaulish</td></tr>
-     * <tr><td>en-GB-oed</td><td>&nbsp;</td><td>en-GB-x-oed</td></tr>
-     * <tr><td>i-default</td><td>&nbsp;</td><td>en-x-i-default</td></tr>
-     * <tr><td>i-enochian</td><td>&nbsp;</td><td>und-x-i-enochian</td></tr>
-     * <tr><td>i-mingo</td><td>&nbsp;</td><td>see-x-i-mingo</td></tr>
-     * <tr><td>zh-min</td><td>&nbsp;</td><td>nan-x-zh-min</td></tr>
-     * </tbody>
-     * </table>
-     *
-     * <p>For a list of all grandfathered tags, see the
-     * IANA Language Subtag Registry (search for "Type: grandfathered").
+     * <p>Note that a few legacy tags have no modern replacement;
+     * these will be converted using the fallback described in
+     * the first paragraph, so some information might be lost.
      *
      * <p><b>Note</b>: there is no guarantee that <code>toLanguageTag</code>
      * and <code>forLanguageTag</code> will round-trip.
@@ -3491,7 +3450,7 @@
          * Resets the Builder to match the provided IETF BCP 47
          * language tag.  Discards the existing state.  Null and the
          * empty string cause the builder to be reset, like {@link
-         * #clear}.  Grandfathered tags (see {@link
+         * #clear}.  Legacy tags (see {@link
          * ULocale#forLanguageTag}) are converted to their canonical
          * form before being processed.  Otherwise, the language tag
          * must be well-formed (see {@link ULocale}) or an exception is
diff --git a/icu4j/main/classes/translit/src/com/ibm/icu/text/TransliteratorParser.java b/icu4j/main/classes/translit/src/com/ibm/icu/text/TransliteratorParser.java
index 5398021..d578e2f 100644
--- a/icu4j/main/classes/translit/src/com/ibm/icu/text/TransliteratorParser.java
+++ b/icu4j/main/classes/translit/src/com/ibm/icu/text/TransliteratorParser.java
@@ -1493,7 +1493,7 @@
                 throw new RuntimeException("Variable range exhausted");
             }
             c = variableNext++;
-            // Set a placeholder in the master variables vector that will be
+            // Set a placeholder in the primary variables vector that will be
             // filled in later by setSegmentObject().  We know that we will get
             // called first because setSegmentObject() will call us.
             variablesVector.add(null);
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/LocaleMatcherTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/LocaleMatcherTest.java
index 97e2dab..deaf486 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/LocaleMatcherTest.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/LocaleMatcherTest.java
@@ -365,7 +365,7 @@
     }
 
     @Test
-    public void testMatchGrandfatheredCode() {
+    public void testMatchLegacyCode() {
         final LocaleMatcher matcher = newLocaleMatcher("fr, i_klingon, en_Latn_US");
         assertEquals("en_Latn_US", matcher.getBestMatch("en_GB_oed").toString());
         // assertEquals("tlh", matcher.getBestMatch("i_klingon").toString());
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/data/localeMatcherTest.txt b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/data/localeMatcherTest.txt
index 7a10986..70afcd0 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/data/localeMatcherTest.txt
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/data/localeMatcherTest.txt
@@ -279,7 +279,7 @@
 zh-Hant >> und-TW
 zh >> und-TW
 
-** test: testMatchGrandfatheredCode
+** test: testMatchLegacyCode
 
 @supported=fr, i-klingon, en-Latn-US
 en-GB-oed >> en-Latn-US
@@ -984,7 +984,7 @@
 x-piglatin >> x-bork
 x-bork >> x-bork
 
-** test: MatchGrandfatheredCode
+** test: MatchLegacyCode
 @supported=fr, i-klingon, en-Latn-US
 en-GB-oed >> en-Latn-US
 i-klingon >> tlh
@@ -1525,7 +1525,7 @@
 x-piglatin >> fr
 x-bork >> x-bork
 
-** test: grandfathered codes
+** test: legacy codes
 @supported=fr, i-klingon, en-Latn-US
 en-GB-oed >> en-Latn-US
 i-klingon >> tlh
diff --git a/icu4j/main/tests/translit/src/com/ibm/icu/dev/test/translit/langtagRegex.txt b/icu4j/main/tests/translit/src/com/ibm/icu/dev/test/translit/langtagRegex.txt
index 696750a..26ba85b 100644
--- a/icu4j/main/tests/translit/src/com/ibm/icu/dev/test/translit/langtagRegex.txt
+++ b/icu4j/main/tests/translit/src/com/ibm/icu/dev/test/translit/langtagRegex.txt
@@ -38,14 +38,15 @@
 
 $privateUse = $x (?: $s $alphanum{1,8} )+ ; # "x" 1*("-" (1*8alphanum))
 
-# Define certain grandfathered codes, since otherwise the regex is pretty useless.
+# Define certain legacy language tags (marked as “Type: grandfathered” in BCP 47),
+# since otherwise the regex is pretty useless.
 # Since these are limited, this is safe even later changes to the registry --
 # the only oddity is that it might change the type of the tag, and thus
 # the results from the capturing groups.
 # http://www.iana.org/assignments/language-subtag-registry
 # Note that these have to be compared case insensitively, requiring (?i) below.
 
-$grandfathered  = en $s GB $s oed
+$legacy  = en $s GB $s oed
       | i $s (?: ami | bnn | default | enochian | hak | klingon | lux | mingo | navajo | pwn | tao | tay | tsu )
       | no $s (?: bok | nyn )
       | sgn $s (?: BE $s (?: fr | nl) | CH $s de )
@@ -55,7 +56,7 @@
 # For well-formedness, we don't need the ones that would otherwise pass.
 # For validity, they need to be checked.
 
-# $grandfatheredWellFormed = (?:
+# $legacyWellFormed = (?:
 #         art $s lojban
 #     | cel $s gaulish
 #     | zh $s (?: guoyu | hakka | xiang )
@@ -78,12 +79,12 @@
       (?: $s ( $privateUse ) )? 5%);
 
 # Here is the final breakdown, with capturing groups for each of these components
-# The variants, extensions, grandfathered, and private-use may have interior '-'
+# The variants, extensions, legacy, and private-use may have interior '-'
  
 $root = (?i) # case-insensitive
   (?:
       $langtag 90%
     | ( $privateUse ) 5%
-    | ( $grandfathered ) 5%)
+    | ( $legacy ) 5%)
 #    (?: \@ $keywords )? 5%
     ;
diff --git a/icu4j/tools/misc/src/com/ibm/icu/dev/tool/translit/dumpICUrules.bat b/icu4j/tools/misc/src/com/ibm/icu/dev/tool/translit/dumpICUrules.bat
index 01e7c39..a6081db 100755
--- a/icu4j/tools/misc/src/com/ibm/icu/dev/tool/translit/dumpICUrules.bat
+++ b/icu4j/tools/misc/src/com/ibm/icu/dev/tool/translit/dumpICUrules.bat
@@ -253,7 +253,7 @@
     print C_INDEX <<END;
 //--------------------------------------------------------------------
 // N.B.: This file has been generated mechanically from the
-// corresponding ICU4J file, which is the master file that receives
+// corresponding ICU4J file, which is the primary file that receives
 // primary updates.  The colon-delimited fields have been split into
 // separate strings.  For 'file' and 'internal' lines, the encoding
 // field has been deleted, since the encoding is processed at build
diff --git a/tools/cldr/cldr-to-icu/src/main/java/org/unicode/icu/tool/cldrtoicu/SupplementalData.java b/tools/cldr/cldr-to-icu/src/main/java/org/unicode/icu/tool/cldrtoicu/SupplementalData.java
index ddc6478..57c6df8 100644
--- a/tools/cldr/cldr-to-icu/src/main/java/org/unicode/icu/tool/cldrtoicu/SupplementalData.java
+++ b/tools/cldr/cldr-to-icu/src/main/java/org/unicode/icu/tool/cldrtoicu/SupplementalData.java
@@ -527,7 +527,8 @@
     // ...
     // Remove the script code 'Zzzz' and the region code 'ZZ' if they occur.
     //
-    // Note that this implementation does not need to handle "grandfathered" tags.
+    // Note that this implementation does not need to handle
+    // legacy language tags (marked as “Type: grandfathered” in BCP 47).
     private Optional<LocaleId> addLikelySubtags(String localeId) {
         if (localeId.equals("root")) {
             return Optional.empty();