def fillna(self, value=None, method=None, limit=None):
        """
        Fill NA/NaN values using the specified method.

        Parameters
        ----------
        value : scalar, dict, Series
            If a scalar value is passed it is used to fill all missing values.
            Alternatively, a Series or dict can be used to fill in different
            values for each index. The value should not be a list. The
            value(s) passed should either be in the categories or should be
            NaN.
        method : {'backfill', 'bfill', 'pad', 'ffill', None}, default None
            Method to use for filling holes in reindexed Series
            pad / ffill: propagate last valid observation forward to next valid
            backfill / bfill: use NEXT valid observation to fill gap
        limit : int, default None
            (Not implemented yet for Categorical!)
            If method is specified, this is the maximum number of consecutive
            NaN values to forward/backward fill. In other words, if there is
            a gap with more than this number of consecutive NaNs, it will only
            be partially filled. If method is not specified, this is the
            maximum number of entries along the entire axis where NaNs will be
            filled.

        Returns
        -------
        filled : Categorical with NA/NaN filled
        """
        value, method = validate_fillna_kwargs(
            value, method, validate_scalar_dict_value=False
        )

        if value is None:
            value = np.nan
        if limit is not None:
            raise NotImplementedError("specifying a limit for fillna has not "
                                      "been implemented yet")

        codes = self._codes

        # pad / bfill
        if method is not None:

            values = self.to_dense().reshape(-1, len(self))
            values = interpolate_2d(values, method, 0, None,
                                    value).astype(self.categories.dtype)[0]
            codes = _get_codes_for_values(values, self.categories)

        else:

            # If value is a dict or a Series (a dict value has already
            # been converted to a Series)
            if isinstance(value, ABCSeries):
                if not value[~value.isin(self.categories)].isna().all():
                    raise ValueError("fill value must be in categories")

                values_codes = _get_codes_for_values(value, self.categories)
                indexer = np.where(values_codes != -1)
                codes[indexer] = values_codes[values_codes != -1]

            # If value is not a dict or Series it should be a scalar
            elif is_hashable(value):
                if not isna(value) and value not in self.categories:
                    raise ValueError("fill value must be in categories")

                mask = codes == -1
                if mask.any():
                    codes = codes.copy()
                    if isna(value):
                        codes[mask] = -1
                    else:
                        codes[mask] = self.categories.get_loc(value)

            else:
                raise TypeError('"value" parameter must be a scalar, dict '
                                'or Series, but you passed a '
                                '"{0}"'.format(type(value).__name__))

        return self._constructor(codes, dtype=self.dtype, fastpath=True)